Home | History | Annotate | Download | only in reflow
      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"
      9 #include "layoutprovider_taggedpdf.h"
     10 IPDF_LayoutProcessor* IPDF_LayoutProcessor::Create_LayoutProcessor_Reflow(FX_FLOAT TopIndent, FX_FLOAT fWidth, FX_FLOAT fHeight, void* pReflowedPage, int flags, FX_FLOAT lineSpace )
     11 {
     12     if(pReflowedPage == NULL || fWidth <= 20) {
     13         return NULL;
     14     }
     15     CPDF_LayoutProcessor_Reflow* pReflowEngine = new CPDF_LayoutProcessor_Reflow();
     16     pReflowEngine->Init(TopIndent, fWidth, fHeight, (CPDF_ReflowedPage*)pReflowedPage, flags, lineSpace);
     17     return pReflowEngine;
     18 }
     19 CPDF_LayoutProcessor_Reflow::CPDF_LayoutProcessor_Reflow()
     20 {
     21     m_pPause = NULL;
     22     m_pLayoutElement = NULL;
     23     m_fRefWidth = 0;
     24     m_fRefWidth = 0;
     25     m_fCurrLineWidth = 0;
     26     m_fCurrLineHeight = 0;
     27     m_bIllustration = FALSE;
     28     m_pPreObj = NULL;
     29     m_pCurrLine = new CRF_DataPtrArray(50);
     30     m_pTempLine = new CRF_DataPtrArray(50);
     31     m_StartIndent = 0;
     32     m_PausePosition = 0;
     33 }
     34 CPDF_LayoutProcessor_Reflow::~CPDF_LayoutProcessor_Reflow()
     35 {
     36     if (m_pCurrLine) {
     37         m_pCurrLine->RemoveAll();
     38         delete m_pCurrLine;
     39     }
     40     m_pCurrLine = NULL;
     41     if (m_pTempLine) {
     42         m_pTempLine->RemoveAll();
     43         delete m_pTempLine;
     44     }
     45     m_pTempLine = NULL;
     46 }
     47 void CPDF_LayoutProcessor_Reflow::Init(FX_FLOAT TopIndent, FX_FLOAT fWidth, FX_FLOAT fHeight, CPDF_ReflowedPage* pReflowedPage, int flags, FX_FLOAT lineSpace)
     48 {
     49     m_pLayoutElement = NULL;
     50     m_TopIndent = TopIndent;
     51     m_Status = LayoutReady;
     52     m_flags = flags;
     53     m_pReflowedPage = pReflowedPage;
     54     m_fScreenHeight = fHeight;
     55     m_fRefWidth = fWidth;
     56     m_fCurrLineHeight = 0;
     57     m_fCurrLineWidth = 0;
     58     m_fLineSpace = lineSpace;
     59     pReflowedPage->m_PageWidth = fWidth;
     60     pReflowedPage->m_PageHeight = TopIndent;
     61 }
     62 void CPDF_LayoutProcessor_Reflow::FitPageMode()
     63 {
     64     if(m_flags & RF_PARSER_PAGEMODE && m_fScreenHeight > 20) {
     65         float fitPageHeight = m_fScreenHeight;
     66         CPDF_ReflowedPage* pRFPage = m_pReflowedPage;
     67         int count = pRFPage->m_pReflowed->GetSize();
     68         CFX_WordArray dy;
     69         dy.Add(0);
     70         int pos = 0;
     71         int screenCount = 1;
     72         FX_FLOAT h = pRFPage->GetPageHeight();
     73         while (h > screenCount * fitPageHeight) {
     74             FX_FLOAT tempPageHeight = screenCount * fitPageHeight;
     75             int j = 0;
     76             FX_FLOAT tempDy = 0;
     77             for(int i = 0; i < count; i++) {
     78                 CRF_Data* pData = (*pRFPage->m_pReflowed)[i];
     79                 FX_FLOAT posY;
     80                 posY = pData->m_PosY;
     81                 if(FXSYS_fabs(posY) > tempPageHeight &&
     82                         FXSYS_fabs(posY + pData->m_Height) < tempPageHeight) {
     83                     if(j == 0) {
     84                         j = i;
     85                     }
     86                     if(pData->m_Height > fitPageHeight) {
     87                         FX_FLOAT zoom;
     88                         FX_FLOAT spaceh = screenCount * fitPageHeight + posY + pData->m_Height;
     89                         if(spaceh < fitPageHeight / 3 * 2) {
     90                             spaceh = fitPageHeight;
     91                         }
     92                         zoom = spaceh / pData->m_Height;
     93                         tempDy = spaceh - pData->m_Height;
     94                         pData->m_Height = spaceh;
     95                         pData->m_Width *= zoom;
     96                         break;
     97                     }
     98                     FX_FLOAT dy = pData->m_PosY + pData->m_Height + tempPageHeight;
     99                     if(dy > tempDy) {
    100                         tempDy = dy;
    101                     }
    102                 } else if(FXSYS_fabs(posY + pData->m_Height) > tempPageHeight) {
    103                     break;
    104                 }
    105             }
    106             for(; j < count; j++) {
    107                 CRF_Data* pData = (*pRFPage->m_pReflowed)[j];
    108                 FX_FLOAT posY;
    109                 posY = pData->m_PosY;
    110                 if(FXSYS_fabs(posY) > tempPageHeight ) {
    111                     pData->m_PosY -= tempDy;
    112                 }
    113                 if(pData->m_Height >= fitPageHeight) {
    114                     pData->m_Height = fitPageHeight - 1;
    115                     if(pData->GetType() == CRF_Data::Text) {
    116                         CRF_CharData* pCharData = (CRF_CharData*)pData;
    117                         pCharData->m_pCharState->m_fFontSize = pData->m_Height;
    118                     }
    119                 }
    120             }
    121             pRFPage->m_PageHeight += tempDy;
    122             h += tempDy;
    123             screenCount++;
    124         }
    125     }
    126 }
    127 LayoutStatus CPDF_LayoutProcessor_Reflow::StartProcess(IPDF_LayoutElement* pElement, IFX_Pause* pPause, const CFX_AffineMatrix* pPDFMatrix)
    128 {
    129     if(!pElement) {
    130         return LayoutError;
    131     }
    132     m_pPause = pPause;
    133     m_PDFMatrix = *pPDFMatrix;
    134     m_pRootElement = pElement;
    135     ProcessElement(m_pRootElement, m_fRefWidth);
    136     if(m_Status == LayoutToBeContinued) {
    137         return LayoutToBeContinued;
    138     }
    139     m_Status = LayoutFinished;
    140     FitPageMode();
    141     return LayoutFinished;
    142 }
    143 LayoutStatus CPDF_LayoutProcessor_Reflow::Continue()
    144 {
    145     int size = m_pReflowedPage->m_pReflowed->GetSize();
    146     ProcessElement(m_pRootElement, m_CurrRefWidth);
    147     size = m_pReflowedPage->m_pReflowed->GetSize();
    148     if(m_Status == LayoutReady) {
    149         m_Status = LayoutFinished;
    150         FitPageMode();
    151     }
    152     return m_Status;
    153 }
    154 int CPDF_LayoutProcessor_Reflow::GetPosition()
    155 {
    156     return m_PausePosition;
    157 }
    158 FX_BOOL	CPDF_LayoutProcessor_Reflow::IsCanBreakAfter(FX_DWORD unicode)
    159 {
    160     if(unicode == -1) {
    161         return FALSE;
    162     }
    163     switch(unicode) {
    164         case 40:
    165         case 91:
    166         case 123:
    167             return FALSE;
    168     }
    169     if(unicode >= 256) {
    170         return TRUE;
    171     } else if(unicode >= 48 && unicode <= 57) {
    172         return FALSE;
    173     } else if(unicode >= 64 && unicode <= 90) {
    174         return FALSE;
    175     } else if(unicode >= 97 && unicode <= 122) {
    176         return FALSE;
    177     }
    178     return TRUE;
    179 }
    180 FX_BOOL	CPDF_LayoutProcessor_Reflow::IsCanBreakBefore(FX_DWORD unicode)
    181 {
    182     if(unicode == -1) {
    183         return FALSE;
    184     }
    185     switch(unicode) {
    186         case 33:
    187         case 41:
    188         case 44:
    189         case 46:
    190         case 59:
    191         case 63:
    192         case 93:
    193         case 125:
    194             return FALSE;
    195     }
    196     if(unicode >= 256) {
    197         return TRUE;
    198     } else if(unicode >= 48 && unicode <= 57) {
    199         return FALSE;
    200     } else if(unicode >= 64 && unicode <= 90) {
    201         return FALSE;
    202     } else if(unicode >= 97 && unicode <= 122) {
    203         return FALSE;
    204     }
    205     return TRUE;
    206 }
    207 void CPDF_LayoutProcessor_Reflow::ProcessTable(FX_FLOAT dx)
    208 {
    209     if(m_pReflowedPage->m_pReflowed->GetSize() == 0) {
    210         return;
    211     }
    212     CRF_Table* pTable = m_TableArray.GetAt(m_TableArray.GetSize() - 1);
    213     int rowCount = pTable->m_nCell.GetSize();
    214     int n = 0;
    215     FX_FLOAT* dyRow = FX_Alloc(FX_FLOAT, rowCount + 1);
    216     FXSYS_memset32(dyRow, 0, sizeof(FX_FLOAT) * (rowCount + 1));
    217     dyRow[0] = 0 ;
    218     dyRow[0] = - pTable->m_ReflowPageHeight;
    219     int tableColCount = 0;
    220     int i;
    221     for(i = 0; i < rowCount; i++) {
    222         int colCount = pTable->m_nCell.GetAt(i);
    223         if(colCount > tableColCount) {
    224             tableColCount = colCount;
    225         }
    226     }
    227     int cellCount = tableColCount * rowCount;
    228     RF_TableCell** pVirtualTable = FX_Alloc(RF_TableCell*, cellCount);
    229     FXSYS_memset32(pVirtualTable, 0, sizeof(RF_TableCell*) * cellCount);
    230     for(i = 0; i < rowCount; i++) {
    231         int colCount = pTable->m_nCell.GetAt(i);
    232         FX_FLOAT rowWidth = 0;
    233         int j = 0;
    234         int s = pTable->m_pCellArray.GetSize();
    235         for(j = 0; j < colCount; j++) {
    236             RF_TableCell* pCell = (RF_TableCell*)pTable->m_pCellArray.GetAt(n++);
    237             if(pCell->m_EndPos < pCell->m_BeginPos) {
    238                 continue;
    239             }
    240             int pos = i * tableColCount;
    241             while(pos < cellCount && pVirtualTable[pos] != NULL) {
    242                 pos++;
    243             }
    244             if(pos >= (i + 1) * tableColCount) {
    245                 pos = i * tableColCount + j;
    246             }
    247             int RowSpan = pCell->m_RowSpan;
    248             int ColSpan = pCell->m_ColSpan;
    249             if(RowSpan + i > rowCount) {
    250                 RowSpan = rowCount - i;
    251             }
    252             if(ColSpan + j > colCount) {
    253                 ColSpan = colCount - j;
    254             }
    255             for(int m = 0; m < RowSpan; m++) {
    256                 for(int nn = 0; nn < ColSpan; nn++) {
    257                     if(pos + nn >= cellCount) {
    258                         break;
    259                     }
    260                     pVirtualTable[pos + nn] = pCell;
    261                 }
    262                 pos += tableColCount;
    263             }
    264             FX_FLOAT dxCell = dx;
    265             for(pos = i * tableColCount; pVirtualTable[pos] != pCell && pos < cellCount; pos++) {
    266                 dxCell += (pVirtualTable[pos])->m_MaxWidth;
    267             }
    268             CRF_Data* pData = (*m_pReflowedPage->m_pReflowed)[pCell->m_BeginPos];
    269             FX_FLOAT dy = dyRow[i] - pData->m_Height - pData->m_PosY;
    270             CFX_AffineMatrix matrix(1, 0, 0, 1, dxCell, dy);
    271             Transform(&matrix, m_pReflowedPage->m_pReflowed, pCell->m_BeginPos, pCell->m_EndPos - pCell->m_BeginPos + 1);
    272             if(pCell->m_RowSpan + i <= rowCount) {
    273                 if(FXSYS_fabs(dyRow[pCell->m_RowSpan + i]) < FXSYS_fabs(dyRow[i] - pCell->m_CellHeight)) {
    274                     dyRow[pCell->m_RowSpan + i] = dyRow[i] - pCell->m_CellHeight;
    275                 }
    276             }
    277         }
    278     }
    279     n = 0;
    280     for(i = 0; i < rowCount; i++) {
    281         int colCount = pTable->m_nCell.GetAt(i);
    282         for(int j = 0; j < colCount; j++) {
    283             RF_TableCell* pCell = (RF_TableCell*)pTable->m_pCellArray.GetAt(n++);
    284             switch(pCell->m_BlockAlign) {
    285                 case LayoutAfter: {
    286                         FX_FLOAT dy = dyRow[i + pCell->m_RowSpan] - pCell->m_CellHeight - dyRow[i];
    287                         CFX_AffineMatrix matrix(1, 0, 0, 1, 0, dy);
    288                         Transform(&matrix, m_pReflowedPage->m_pReflowed, pCell->m_BeginPos, pCell->m_EndPos - pCell->m_BeginPos + 1);
    289                     }
    290                     break;
    291                 case LayoutMiddle:
    292                 case LayoutJustify: {
    293                         FX_FLOAT dy = (dyRow[i + pCell->m_RowSpan] + pCell->m_CellHeight - dyRow[i]) / 2;
    294                         CFX_AffineMatrix matrix(1, 0, 0, 1, 0, dy);
    295                         Transform(&matrix, m_pReflowedPage->m_pReflowed, pCell->m_BeginPos, pCell->m_EndPos - pCell->m_BeginPos + 1);
    296                         break;
    297                     }
    298                 default:
    299                     break;
    300             }
    301         }
    302     }
    303     CRF_Data* pData = (*m_pReflowedPage->m_pReflowed)[m_pReflowedPage->m_pReflowed->GetSize() - 1];
    304     m_pReflowedPage->m_PageHeight = - dyRow[rowCount] + pData->m_Height;
    305     FX_Free(pVirtualTable);
    306     FX_Free(dyRow);
    307     int size = pTable->m_pCellArray.GetSize();
    308     for(i = 0; i < size; i++) {
    309         RF_TableCell* pCell = pTable->m_pCellArray.GetAt(i);
    310         FX_Free(pCell);
    311     }
    312     pTable->m_pCellArray.RemoveAll();
    313     pTable->m_nCell.RemoveAll();
    314     int s = sizeof(CRF_Table);
    315     delete pTable;
    316     m_TableArray.RemoveAt(m_TableArray.GetSize() - 1);
    317 }
    318 CFX_FloatRect CPDF_LayoutProcessor_Reflow::GetElmBBox(IPDF_LayoutElement* pElement)
    319 {
    320     CFX_FloatRect rect;
    321     int objCount = pElement->CountObjects();
    322     int count = pElement->CountChildren();
    323     if(objCount == 0 && count == 0) {
    324         return rect;
    325     }
    326     CFX_AffineMatrix matrix;
    327     int i;
    328     for(i = 0; i < objCount; i++) {
    329         CPDF_PageObject* pObj = pElement->GetObject(0);
    330         if(!pObj) {
    331             continue;
    332         }
    333         if( rect.Height() == 0 ) {
    334             rect = pObj->GetBBox(&matrix);
    335         } else {
    336             rect.Union(pObj->GetBBox(&matrix));
    337         }
    338     }
    339     for(i = 0; i < count; i++) {
    340         IPDF_LayoutElement* pChildElement = pElement->GetChild(i);
    341         if( rect.Height() == 0 ) {
    342             rect = GetElmBBox(pChildElement);
    343         } else {
    344             rect.Union(GetElmBBox(pChildElement));
    345         }
    346     }
    347     return rect;
    348 }
    349 FX_FLOAT CPDF_LayoutProcessor_Reflow::GetElmWidth(IPDF_LayoutElement* pElement)
    350 {
    351     if(!pElement) {
    352         return 0;
    353     }
    354     LayoutType layoutType = pElement->GetType();
    355     FX_FLOAT width = 0;
    356     if(layoutType == LayoutTable || layoutType == LayoutTableDataCell || layoutType == LayoutTableHeaderCell) {
    357         width = pElement->GetNumberAttr(LayoutWidth);
    358         if(width > 0) {
    359             return width;
    360         }
    361     } else if( layoutType == LayoutTableRow) {
    362         int count = pElement->CountChildren();
    363         for(int i = 0; i < count; i++) {
    364             IPDF_LayoutElement* pElm = pElement->GetChild(i);
    365             width += pElm->GetNumberAttr(LayoutWidth);
    366         }
    367         if(width > 0) {
    368             return width;
    369         }
    370     }
    371     CFX_FloatRect rect = GetElmBBox(pElement);
    372     return rect.Width();
    373 }
    374 FX_BOOL GetIntersection(FX_FLOAT low1, FX_FLOAT high1, FX_FLOAT low2, FX_FLOAT high2,
    375                         FX_FLOAT& interlow, FX_FLOAT& interhigh);
    376 FX_BOOL IsSameLine(FX_BOOL bHorizontal, CFX_FloatRect Rect1, CFX_FloatRect Rect2)
    377 {
    378     if(bHorizontal) {
    379         FX_FLOAT inter_top, inter_bottom;
    380         if (!GetIntersection(Rect1.bottom, Rect1.top, Rect2.bottom, Rect2.top,
    381                              inter_bottom, inter_top)) {
    382             return FALSE;
    383         }
    384         FX_FLOAT lineHeight = Rect1.top - Rect1.bottom;
    385         if(lineHeight > 20 && lineHeight > Rect2.Height() * 2) {
    386             return FALSE;
    387         }
    388         if(lineHeight > 5 && Rect2.Height() / 2 > lineHeight) {
    389             return FALSE;
    390         }
    391         FX_FLOAT inter_h = inter_top - inter_bottom;
    392         if (inter_h < (lineHeight) / 2 && inter_h < Rect2.Height() / 2) {
    393             return FALSE;
    394         }
    395     } else {
    396         FX_FLOAT inter_left, inter_right;
    397         if(!GetIntersection(Rect1.left, Rect1.right, Rect2.left, Rect2.right, inter_left, inter_right)) {
    398             return FALSE;
    399         }
    400         FX_FLOAT inter_w = inter_right - inter_left;
    401         if (inter_w < (Rect1.right - Rect1.left) / 2 && inter_w < (Rect2.right - Rect2.left) / 2) {
    402             return FALSE;
    403         }
    404     }
    405     return TRUE;
    406 }
    407 FX_INT32 IsCanMergeParagraph(IPDF_LayoutElement* pPrevElement, IPDF_LayoutElement* pNextElement)
    408 {
    409     FX_INT32 analogial = 100;
    410     FX_INT32 nPrevObj = pPrevElement->CountObjects(), i;
    411     CPDF_PageObject* pPrevObj = NULL;
    412     CFX_FloatRect prevRect, rect;
    413     CFX_PtrArray prevLine, line;
    414     FX_BOOL bParagraphStart = FALSE;
    415     for(i = 0; i < nPrevObj; i++) {
    416         CPDF_PageObject* pObj = pPrevElement->GetObject(i);
    417         if(!pPrevObj) {
    418             pPrevObj = pObj;
    419             rect = CFX_FloatRect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right, pObj->m_Top);
    420             line.Add(pObj);
    421             continue;
    422         }
    423         CFX_FloatRect objRect = CFX_FloatRect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right, pObj->m_Top);
    424         if(IsSameLine(TRUE, rect, objRect)) {
    425             line.Add(pObj);
    426             rect.Union(objRect);
    427         } else {
    428             prevLine.RemoveAll();
    429             prevLine.Append(line);
    430             prevRect = rect;
    431             line.RemoveAll();
    432             line.Add(pObj);
    433             rect = objRect;
    434             if(!bParagraphStart) {
    435                 if (prevRect.left > rect.left + rect.Height() * 1.5) {
    436                     bParagraphStart = TRUE;
    437                 }
    438             }
    439         }
    440     }
    441     if(prevLine.GetSize()) {
    442         if(FXSYS_fabs(rect.right - prevRect.right) > rect.Height()) {
    443             analogial -= 50;
    444         }
    445     }
    446     CPDF_PageObject* pObj = pPrevElement->GetObject(nPrevObj - 1);
    447     if(pObj->m_Type == PDFPAGE_TEXT) {
    448         CPDF_TextObject* pText = (CPDF_TextObject*)pObj;
    449         FX_INT32 nItem = pText->CountItems();
    450         CPDF_TextObjectItem item;
    451         pText->GetItemInfo(nItem - 1, &item);
    452         CFX_WideString wStr = pText->GetFont()->UnicodeFromCharCode(item.m_CharCode);
    453         if(wStr.IsEmpty()) {
    454             wStr = (FX_WCHAR)item.m_CharCode;
    455         }
    456         FX_WCHAR wch = wStr.GetAt(wStr.GetLength() - 1);
    457         switch(wch) {
    458             case '.':
    459             case 12290:
    460             case 65311:
    461             case 63:
    462             case 33:
    463             case 65281:
    464                 analogial -= 50;
    465                 break;
    466         }
    467     }
    468     prevLine.RemoveAll();
    469     prevLine.Append(line);
    470     line.RemoveAll();
    471     FX_INT32 nNextObj = pNextElement->CountObjects();
    472     pPrevObj = NULL;
    473     FX_BOOL bFirst = TRUE;
    474     for(i = 0; i < nNextObj; i++) {
    475         CPDF_PageObject* pObj = pNextElement->GetObject(i);
    476         if(!pPrevObj) {
    477             pPrevObj = pObj;
    478             rect = CFX_FloatRect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right, pObj->m_Top);
    479             line.Add(pObj);
    480             continue;
    481         }
    482         CFX_FloatRect objRect = CFX_FloatRect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right, pObj->m_Top);
    483         if(IsSameLine(TRUE, rect, objRect)) {
    484             line.Add(pObj);
    485             rect.Union(objRect);
    486         } else {
    487             if(FXSYS_fabs(rect.right - prevRect.right) < rect.Height() && FXSYS_fabs(rect.left - prevRect.left) < rect.Height()) {
    488                 analogial += 50;
    489             }
    490             prevLine.RemoveAll();
    491             prevLine.Append(line);
    492             prevRect = rect;
    493             line.RemoveAll();
    494             line.Add(pObj);
    495             rect = objRect;
    496             if(!bFirst) {
    497                 break;
    498             }
    499             bFirst = FALSE;
    500         }
    501     }
    502     if(prevLine.GetSize()) {
    503         if(bParagraphStart) {
    504             if(prevRect.left - rect.left > rect.Height() && prevRect.left - rect.left < rect.Height() * 3) {
    505                 analogial -= 50;
    506             }
    507         } else {
    508             if(FXSYS_fabs(prevRect.left - rect.left) < rect.Height()) {
    509                 analogial -= 50;
    510             }
    511         }
    512     }
    513     return analogial;
    514 }
    515 void CPDF_LayoutProcessor_Reflow::ProcessElement(IPDF_LayoutElement* pElement, FX_FLOAT reflowWidth)
    516 {
    517     if(pElement == NULL) {
    518         return;
    519     }
    520     if(m_Status == LayoutReady) {
    521         LayoutType layoutType = pElement->GetType();
    522         FX_INT32 ElementType = GetElementTypes(layoutType);
    523         switch(ElementType) {
    524             case SST_IE:
    525                 m_bIllustration = TRUE;
    526                 break;
    527             case SST_BLSE:
    528                 FinishedCurrLine();
    529                 FX_FLOAT StartIndent = 0;
    530                 if(IPDF_LayoutElement* pParent = pElement->GetParent()) {
    531                     StartIndent = pParent->GetNumberAttr(LayoutStartIndent);
    532                 }
    533                 FX_FLOAT currStartIndent = pElement->GetNumberAttr(LayoutStartIndent);
    534                 m_StartIndent = ConverWidth(currStartIndent);
    535                 FX_FLOAT width = reflowWidth;
    536                 if(StartIndent != currStartIndent) {
    537                     reflowWidth -= m_StartIndent;
    538                 }
    539                 FX_FLOAT spaceBefore = pElement->GetNumberAttr(LayoutSpaceBefore);
    540                 m_pReflowedPage->m_PageHeight += spaceBefore;
    541                 m_TextAlign = pElement->GetEnumAttr(LayoutTextAlign);
    542                 if(IPDF_LayoutElement* pParent = pElement->GetParent()) {
    543                     StartIndent = pParent->GetNumberAttr(LayoutEndIndent);
    544                     FX_FLOAT currEndIndent = pElement->GetNumberAttr(LayoutEndIndent);
    545                     if(StartIndent != currStartIndent) {
    546                         reflowWidth -= ConverWidth(currEndIndent);
    547                     }
    548                 }
    549                 if(reflowWidth * 2 < width) {
    550                     reflowWidth = width;
    551                     m_StartIndent = 0;
    552                 }
    553                 break;
    554         }
    555         switch(layoutType) {
    556             case LayoutTable: {
    557                     CRF_Table* pTable = new CRF_Table;
    558                     m_TableArray.Add(pTable);
    559                     pTable->m_ReflowPageHeight = m_pReflowedPage->m_PageHeight;
    560                     pTable->m_TableWidth = GetElmWidth(pElement);
    561                     break;
    562                 }
    563             case LayoutTableRow: {
    564                     if(!m_TableArray.GetSize()) {
    565                         break;
    566                     }
    567                     int count = pElement->CountChildren();
    568                     CRF_Table* pTable = m_TableArray.GetAt(m_TableArray.GetSize() - 1);
    569                     int f = 0;
    570                     for(int i = 0; i < count; i++) {
    571                         IPDF_LayoutElement* pChildElement = pElement->GetChild(i);
    572                         LayoutType type = pChildElement->GetType();
    573                         if(type == LayoutTableDataCell || type == LayoutTableHeaderCell) {
    574                             f++;
    575                         }
    576                     }
    577                     pTable->m_nCell.Add(f);
    578                     break;
    579                 }
    580             case LayoutTableDataCell:
    581             case LayoutTableHeaderCell: {
    582                     if(!m_TableArray.GetSize()) {
    583                         break;
    584                     }
    585                     RF_TableCell* pCell = FX_Alloc(RF_TableCell, 1);
    586                     FXSYS_memset32(pCell, 0 , sizeof(RF_TableCell));
    587                     CRF_Table* pTable = m_TableArray.GetAt(m_TableArray.GetSize() - 1);
    588                     int pos = pTable->m_nCell.GetSize() - 1;
    589                     pCell->m_BeginPos = m_pReflowedPage->m_pReflowed->GetSize();
    590                     FX_FLOAT cellWidth = pElement->GetNumberAttr(LayoutWidth);
    591                     if(cellWidth == 0 || pCell->m_MaxWidth > pTable->m_TableWidth) {
    592                         CRF_Table* pTable = m_TableArray.GetAt(m_TableArray.GetSize() - 1);
    593                         pCell->m_MaxWidth = reflowWidth / pTable->m_nCell.GetAt(pTable->m_nCell.GetSize() - 1);
    594                     } else {
    595                         pCell->m_MaxWidth = pElement->GetNumberAttr(LayoutWidth) * reflowWidth / pTable->m_TableWidth;
    596                     }
    597                     pCell->m_ColSpan = (int)(pElement->GetNumberAttr(LayoutColSpan));
    598                     pCell->m_RowSpan = (int)(pElement->GetNumberAttr(LayoutRowSpan));
    599                     if(!pCell->m_ColSpan) {
    600                         pCell->m_ColSpan = 1;
    601                     }
    602                     if(!pCell->m_RowSpan ) {
    603                         pCell->m_RowSpan = 1;
    604                     }
    605                     pCell->m_BlockAlign = pElement->GetEnumAttr(LayoutBlockAlign);
    606                     m_TextAlign = pElement->GetEnumAttr(LayoutInlineAlign);
    607                     pCell->m_PosX = 0;
    608                     pCell->m_PosY = 0;
    609                     reflowWidth = pCell->m_MaxWidth;
    610                     pTable->m_pCellArray.Add(pCell);
    611                     break;
    612                 }
    613             default:
    614                 break;
    615         }
    616         m_fLineHeight = pElement->GetNumberAttr(LayoutLineHeight);
    617         int ReflowedSize = m_pReflowedPage->m_pReflowed->GetSize();
    618         if(pElement->CountObjects()) {
    619             ProcessObjs(pElement, reflowWidth);
    620         }
    621     }
    622     int count = pElement->CountChildren();
    623     for(int i = 0; i < count; i++) {
    624         IPDF_LayoutElement* pChildElement = pElement->GetChild(i);
    625         ProcessElement(pChildElement, reflowWidth);
    626         if(m_pPause && m_pRootElement == pElement && m_Status != LayoutToBeContinued ) {
    627             if(m_pPause->NeedToPauseNow()) {
    628                 m_pLayoutElement = pChildElement;
    629                 m_Status = LayoutToBeContinued;
    630                 m_CurrRefWidth = reflowWidth;
    631                 m_PausePosition = (i + 1) * 100 / (count + 1);
    632                 return ;
    633             }
    634         }
    635         if(m_Status == LayoutToBeContinued && m_pLayoutElement == pChildElement) {
    636             m_Status = LayoutReady;
    637         }
    638     }
    639     if(m_Status == LayoutReady) {
    640         FX_FLOAT dx = 0;
    641         LayoutType layoutType = pElement->GetType();
    642         FX_INT32 ElementType = GetElementTypes(layoutType);
    643         switch(ElementType) {
    644             case SST_IE:
    645                 m_bIllustration = FALSE;
    646                 FinishedCurrLine();
    647                 break;
    648             case SST_BLSE:
    649                 FinishedCurrLine();
    650                 FX_FLOAT StartIndent = 0;
    651                 if(IPDF_LayoutElement* pParent = pElement->GetParent()) {
    652                     StartIndent = pParent->GetNumberAttr(LayoutStartIndent);
    653                 }
    654                 FX_FLOAT currStartIndent = pElement->GetNumberAttr(LayoutStartIndent);
    655                 if(StartIndent != currStartIndent) {
    656                     reflowWidth += ConverWidth(currStartIndent);
    657                     dx += ConverWidth(currStartIndent);
    658                 }
    659                 FX_FLOAT spaceAfter = pElement->GetNumberAttr(LayoutSpaceAfter);
    660                 m_pReflowedPage->m_PageHeight += spaceAfter;
    661                 break;
    662         }
    663         switch(layoutType) {
    664             case LayoutTableDataCell:
    665             case LayoutTableHeaderCell: {
    666                     if(!m_TableArray.GetSize()) {
    667                         break;
    668                     }
    669                     CRF_Table* pTable = m_TableArray.GetAt(m_TableArray.GetSize() - 1);
    670                     RF_TableCell* pCell = pTable->m_pCellArray.GetAt(pTable->m_pCellArray.GetSize() - 1);
    671                     pCell->m_EndPos = m_pReflowedPage->m_pReflowed->GetSize() - 1;
    672                     if(pCell->m_EndPos < pCell->m_BeginPos) {
    673                         pCell->m_CellHeight = 0;
    674                     } else {
    675                         CRF_Data* pBeginData = (*m_pReflowedPage->m_pReflowed)[pCell->m_BeginPos];
    676                         CRF_Data* pEndData = (*m_pReflowedPage->m_pReflowed)[pCell->m_EndPos];
    677                         pCell->m_CellHeight = pBeginData->m_Height > pEndData->m_Height ? pBeginData->m_Height : pEndData->m_Height;
    678                         pCell->m_CellHeight -= pEndData->m_PosY - pBeginData->m_PosY;
    679                     }
    680                     break;
    681                 }
    682             case LayoutTableRow: {
    683                     if(!m_TableArray.GetSize()) {
    684                         break;
    685                     }
    686                     CRF_Table* pTable = m_TableArray.GetAt(m_TableArray.GetSize() - 1);
    687                     if(pTable->m_nCol == 0) {
    688                         pTable->m_nCol = pTable->m_pCellArray.GetSize();
    689                     }
    690                     break;
    691                 }
    692             case LayoutTable: {
    693                     ProcessTable(dx);
    694                     break;
    695                 }
    696             default:
    697                 if(dx) {
    698                     CFX_AffineMatrix matrix(1, 0, 0, 1, dx, 0);
    699                     int ReflowedSize = m_pReflowedPage->m_pReflowed->GetSize();
    700                     Transform(&matrix, m_pReflowedPage->m_pReflowed, ReflowedSize, m_pReflowedPage->m_pReflowed->GetSize() - ReflowedSize);
    701                 }
    702         }
    703     }
    704     if(m_pRootElement == pElement) {
    705         m_PausePosition = 100;
    706     }
    707 }
    708 FX_INT32 CPDF_LayoutProcessor_Reflow::GetElementTypes(LayoutType layoutType)
    709 {
    710     switch(layoutType) {
    711         case LayoutParagraph:
    712         case LayoutHeading:
    713         case LayoutHeading1:
    714         case LayoutHeading2:
    715         case LayoutHeading3:
    716         case LayoutHeading4:
    717         case LayoutHeading5:
    718         case LayoutHeading6:
    719         case LayoutList:
    720         case LayoutListItem:
    721         case LayoutListLabel:
    722         case LayoutListBody:
    723         case LayoutTable:
    724         case LayoutTableHeaderCell:
    725         case LayoutTableDataCell:
    726         case LayoutTableRow:
    727         case LayoutTableHeaderGroup:
    728         case LayoutTableBodyGroup:
    729         case LayoutTableFootGroup:
    730         case LayoutTOCI:
    731         case LayoutCaption:
    732             return SST_BLSE;
    733         case LayoutFigure:
    734         case LayoutFormula:
    735         case LayoutForm:
    736             return SST_IE;
    737         case LayoutSpan:
    738         case LayoutQuote:
    739         case LayoutNote:
    740         case LayoutReference:
    741         case LayoutBibEntry:
    742         case LayoutCode:
    743         case LayoutLink:
    744         case LayoutAnnot:
    745         case LayoutRuby:
    746         case LayoutWarichu:
    747             return SST_ILSE;
    748         default:
    749             return SST_GE;
    750     }
    751     return FALSE;
    752 }
    753 FX_FLOAT	CPDF_LayoutProcessor_Reflow::ConverWidth(FX_FLOAT width)
    754 {
    755     return width;
    756 }
    757 void CPDF_LayoutProcessor_Reflow::ProcessObject(CPDF_PageObject* pObj, FX_FLOAT reflowWidth, CFX_AffineMatrix objMatrix)
    758 {
    759     if(!pObj) {
    760         return;
    761     }
    762     if(pObj->m_Type == PDFPAGE_TEXT) {
    763         ProcessTextObject( (CPDF_TextObject *)pObj, reflowWidth, objMatrix);
    764     } else if(pObj->m_Type == PDFPAGE_IMAGE) {
    765         if(!(m_flags & RF_PARSER_IMAGE)) {
    766             return;
    767         }
    768         CPDF_PageObjects* pObjs = new CPDF_PageObjects(FALSE);
    769         FX_POSITION pos = pObjs->GetLastObjectPosition();
    770         pos = pObjs->InsertObject(pos, pObj);
    771         CFX_AffineMatrix matrix;
    772         FX_RECT rect = pObj->GetBBox(&matrix);
    773         CPDF_ImageObject* ImageObj = (CPDF_ImageObject*)pObj;
    774         ProcessUnitaryObjs(pObjs, reflowWidth, objMatrix);
    775         delete pObjs;
    776     } else if(pObj->m_Type == PDFPAGE_PATH) {
    777     } else if(pObj->m_Type == PDFPAGE_FORM) {
    778         CPDF_FormObject* pForm = (CPDF_FormObject*)pObj;
    779         FX_POSITION pos = pForm->m_pForm->GetFirstObjectPosition();
    780         objMatrix.Concat(pForm->m_FormMatrix);
    781         while (pos) {
    782             CPDF_PageObject* pObj1 = pForm->m_pForm->GetNextObject(pos);
    783             ProcessObject(pObj1, reflowWidth, objMatrix);
    784         }
    785     }
    786 }
    787 void CPDF_LayoutProcessor_Reflow::ProcessObjs(IPDF_LayoutElement* pElement, FX_FLOAT reflowWidth)
    788 {
    789     m_fCurrMaxWidth = reflowWidth;
    790     int ObjCount = pElement->CountObjects();
    791     for(int i = 0; i < ObjCount; i++) {
    792         CPDF_PageObject* pObj = pElement->GetObject(i);
    793         ProcessObject(pObj, reflowWidth, m_PDFMatrix);
    794         continue;
    795     }
    796 }
    797 void CPDF_LayoutProcessor_Reflow::AddTemp2CurrLine(int begin, int count)
    798 {
    799     if(begin < 0 || count <= 0 || !m_pReflowedPage || !m_pReflowedPage->m_pReflowed || !m_pTempLine) {
    800         return;
    801     } else {
    802         count += begin;
    803     }
    804     int size = m_pReflowedPage->m_pReflowed->GetSize();
    805     int temps = m_pTempLine->GetSize();
    806     for(int i = begin; i < count; i++) {
    807         CRF_Data* pData = (*m_pTempLine)[i];
    808         AddData2CurrLine(pData);
    809     }
    810 }
    811 void CPDF_LayoutProcessor_Reflow::AddData2CurrLine(CRF_Data* pData)
    812 {
    813     if(pData == NULL || m_pCurrLine == NULL) {
    814         return;
    815     }
    816     m_pCurrLine->Add(pData);
    817     m_fCurrLineWidth = pData->m_PosX + pData->m_Width;
    818     if(pData->m_Height > m_fCurrLineHeight) {
    819         m_fCurrLineHeight = pData->m_Height;
    820     }
    821 }
    822 void CPDF_LayoutProcessor_Reflow::UpdateCurrLine()
    823 {
    824 }
    825 void CPDF_LayoutProcessor_Reflow::Transform(const CFX_AffineMatrix* pMatrix, CRF_DataPtrArray* pDataArray, int beginPos, int count)
    826 {
    827     if (!pDataArray) {
    828         return;
    829     }
    830     if(count == 0) {
    831         count = pDataArray->GetSize();
    832     } else {
    833         count += beginPos;
    834     }
    835     for(int i = beginPos; i < count; i++) {
    836         CRF_Data* pData = (*pDataArray)[i];
    837         Transform(pMatrix, pData);
    838     }
    839 }
    840 void CPDF_LayoutProcessor_Reflow::Transform(const CFX_AffineMatrix* pMatrix, CRF_Data* pData)
    841 {
    842     if(pData->GetType() == CRF_Data::Path) {
    843         CRF_PathData* pPathData = (CRF_PathData*)pData;
    844         pPathData->m_pPath2Device.Concat(*pMatrix);
    845     }
    846     pMatrix->Transform(pData->m_PosX, pData->m_PosY, pData->m_PosX, pData->m_PosY);
    847 }
    848 FX_BOOL CPDF_LayoutProcessor_Reflow::FinishedCurrLine()
    849 {
    850     if (NULL == m_pCurrLine) {
    851         return FALSE;
    852     }
    853     int count = m_pCurrLine->GetSize();
    854     if(count == 0) {
    855         return FALSE;
    856     }
    857     if(m_fLineHeight > m_fCurrLineHeight) {
    858         m_fCurrLineHeight = m_fLineHeight;
    859     } else {
    860         m_fCurrLineHeight += 2;
    861     }
    862     if(m_pReflowedPage->m_pReflowed->GetSize() > 0) {
    863         m_fCurrLineHeight += m_fLineSpace;
    864     }
    865     FX_FLOAT height = m_pReflowedPage->m_PageHeight + m_fCurrLineHeight;
    866     FX_FLOAT lineHeight = m_fLineHeight;
    867     if(lineHeight == 0) {
    868         lineHeight = m_fCurrLineHeight;
    869     }
    870     FX_FLOAT dx = 0;
    871     switch(m_TextAlign) {
    872         case LayoutCenter:
    873             dx = (m_fCurrMaxWidth - m_fCurrLineWidth) / 2;
    874             break;
    875         case LayoutEnd:
    876             dx = m_fCurrMaxWidth - m_fCurrLineWidth;
    877             break;
    878         case LayoutJustify:
    879             break;
    880         default:
    881             break;
    882     }
    883     FX_FLOAT dy = - height;
    884     int refedSize = m_pReflowedPage->m_pReflowed->GetSize();
    885     if(count == 13) {
    886         int a = 0;
    887     }
    888     for(int i = 0; i < count; i++) {
    889         CRF_Data* pData = (*m_pCurrLine)[i];
    890         m_pReflowedPage->m_pReflowed->Add(pData);
    891         FX_FLOAT x = m_StartIndent + dx * (m_TextAlign == LayoutJustify ? i + 1 : 1);
    892         CFX_AffineMatrix matrix(1, 0, 0, 1, x, dy);
    893         Transform(&matrix, pData);
    894     }
    895     m_pCurrLine->RemoveAll();
    896     m_fCurrLineWidth = 0;
    897     m_pReflowedPage->m_PageHeight += m_fCurrLineHeight;
    898     m_fCurrLineHeight = 0;
    899     return TRUE;
    900 }
    901 CRF_CharState* CPDF_LayoutProcessor_Reflow::GetCharState(CPDF_TextObject* pObj, CPDF_Font* pFont, FX_FLOAT fHeight, FX_ARGB color)
    902 {
    903     if (NULL == m_pReflowedPage->m_pCharState) {
    904         return NULL;
    905     }
    906     int count = m_pReflowedPage->m_pCharState->GetSize();
    907     for(int i = count - 1; i >= 0; i--) {
    908         CRF_CharState* pState = (CRF_CharState*)m_pReflowedPage->m_pCharState->GetAt(i);
    909         if(pState->m_Color == color && pState->m_fFontSize == fHeight && pState->m_pFont == pFont && pState->m_pTextObj == pObj) {
    910             return pState;
    911         }
    912     }
    913     CRF_CharState pState;
    914     pState.m_pTextObj = pObj;
    915     pState.m_Color = color;
    916     pState.m_pFont = pFont;
    917     pState.m_fFontSize = fHeight;
    918     int ascent = pFont->GetTypeAscent();
    919     int descent = pFont->GetTypeDescent();
    920     pState.m_fAscent = ascent * fHeight / (ascent - descent);
    921     if(descent == 0) {
    922         pState.m_fDescent = 0;
    923     } else {
    924         pState.m_fDescent = descent * fHeight / (ascent - descent);
    925     }
    926     pState.m_bVert = FALSE;
    927     CPDF_CIDFont *pCIDFont = pFont->GetCIDFont();
    928     if(pCIDFont) {
    929         pState.m_bVert = pCIDFont->IsVertWriting();
    930     }
    931     m_pReflowedPage->m_pCharState->Add(pState);
    932     return (CRF_CharState*)m_pReflowedPage->m_pCharState->GetAt(count);
    933 }
    934 int CPDF_LayoutProcessor_Reflow::GetCharWidth(FX_DWORD charCode, CPDF_Font* pFont) const
    935 {
    936     if(charCode == -1) {
    937         return 0;
    938     }
    939     int w = pFont->GetCharWidthF(charCode);
    940     if(w == 0) {
    941         CFX_ByteString str;
    942         pFont->AppendChar(str, charCode);
    943         w = pFont->GetStringWidth(str, 1);
    944         if(w == 0) {
    945             FX_RECT BBox;
    946             pFont->GetCharBBox(charCode, BBox);
    947             w = BBox.right - BBox.left;
    948         }
    949     }
    950     return w;
    951 }
    952 void CPDF_LayoutProcessor_Reflow::CreateRFData(CPDF_PageObject* pObj, CFX_AffineMatrix* pObjMatrix)
    953 {
    954     if (NULL == m_pReflowedPage->m_pMemoryPool) {
    955         return;
    956     }
    957     if(pObj->m_Type == PDFPAGE_TEXT) {
    958         CPDF_TextObject* pTextObj = (CPDF_TextObject* )pObj;
    959         int count = pTextObj->CountItems();
    960         if(!count) {
    961             return;
    962         }
    963         if(count == 1) {
    964             CPDF_TextObjectItem Item;
    965             pTextObj->GetItemInfo(0, &Item);
    966             if(Item.m_CharCode == 49) {
    967                 int a = 0;
    968             }
    969         }
    970         CPDF_Font * pFont = pTextObj->GetFont();
    971         FX_FLOAT fs = pTextObj->GetFontSize();
    972         FX_FLOAT* pmatrix = pTextObj->m_TextState.GetMatrix();
    973         FX_FLOAT matrix1 = pmatrix[1];
    974         if(pmatrix[2] == 0) {
    975             matrix1 = 0;
    976         }
    977         CFX_AffineMatrix textMatrix(pmatrix[0], matrix1, pmatrix[2], pmatrix[3], 0, 0);
    978         FX_FLOAT height = FXSYS_fabs(textMatrix.TransformDistance(fs));
    979         if(pObjMatrix) {
    980             height = FXSYS_fabs(pObjMatrix->TransformDistance(height));
    981         }
    982         int r = 0, g = 0, b = 0;
    983         pTextObj->m_ColorState.GetFillColor()->GetRGB(r, g, b);
    984         FX_ARGB col = r * 0x10000;
    985         col += g * 0x100;
    986         col += b;
    987         CRF_CharState* pState = GetCharState(pTextObj, pFont, height, col);
    988         FX_FLOAT dx = 0, dy = 0;
    989         FX_RECT ObjBBox;
    990         if(pObjMatrix) {
    991             ObjBBox = pTextObj->GetBBox(pObjMatrix);
    992             dx = (float)ObjBBox.left;
    993             dy = (float)ObjBBox.bottom;
    994         } else {
    995             CFX_AffineMatrix matrix;
    996             ObjBBox = pTextObj->GetBBox(&matrix);
    997         }
    998         FX_FLOAT objWidth = 0;
    999         CFX_ByteString str;
   1000         FX_BOOL bOrder = TRUE;
   1001         CFX_PtrArray tempArray;
   1002         int i = 0;
   1003         CPDF_TextObjectItem Item;
   1004         pTextObj->GetItemInfo(i, &Item);
   1005         dx = Item.m_OriginX;
   1006         dy = Item.m_OriginY;
   1007         textMatrix.Transform(Item.m_OriginX, Item.m_OriginY, dx, dy);
   1008         CRF_CharData* pLastData = NULL;
   1009         FX_FLOAT horzScale = pTextObj->m_TextState.GetFontSizeV() / pTextObj->m_TextState.GetFontSizeH();
   1010         while(i < count) {
   1011             pTextObj->GetItemInfo(i, &Item);
   1012             if(Item.m_CharCode == -1) {
   1013                 i++;
   1014                 continue;
   1015             }
   1016             FX_FLOAT OriginX, OriginY;
   1017             textMatrix.Transform(Item.m_OriginX, Item.m_OriginY, OriginX, OriginY);
   1018             CRF_CharData* pData = (CRF_CharData*)m_pReflowedPage->m_pMemoryPool->Alloc(sizeof(CRF_CharData));
   1019             if (NULL == pData) {
   1020                 continue;
   1021             }
   1022             pData->m_Type = CRF_Data::Text;
   1023             if(FXSYS_fabs(OriginY - dy) > FXSYS_fabs(OriginX - dx)) {
   1024                 pData->m_PosY = dy;
   1025                 pData->m_PosX = pLastData->m_PosX + pLastData->m_Width + textMatrix.TransformDistance(pTextObj->m_TextState.GetObject()->m_CharSpace);
   1026             } else {
   1027                 pData->m_PosY = OriginY;
   1028                 pData->m_PosX = OriginX;
   1029             }
   1030             int size = tempArray.GetSize();
   1031             if(size && pData->m_PosX < pLastData->m_PosX ) {
   1032                 for (int j = 0; j < size; j++) {
   1033                     CRF_CharData* pData1 = (CRF_CharData*)tempArray.GetAt(j);
   1034                     if(pData1->m_PosX > pData->m_PosX) {
   1035                         tempArray.InsertAt(j, pData);
   1036                         break;
   1037                     }
   1038                 }
   1039             } else {
   1040                 tempArray.Add(pData);
   1041             }
   1042             pLastData = pData;
   1043             pData->m_CharCode = Item.m_CharCode;
   1044             pData->m_Height = FXSYS_fabs(height);
   1045             int w = GetCharWidth(Item.m_CharCode, pFont);
   1046             pData->m_Width = FXSYS_fabs(fs * textMatrix.TransformDistance((FX_FLOAT)w) / 1000);
   1047             if(horzScale) {
   1048                 pData->m_Width /= horzScale;
   1049             }
   1050             pData->m_pCharState = pState;
   1051             i++;
   1052         }
   1053         count = tempArray.GetSize();
   1054         for (int j = 0; j < count; j++) {
   1055             CRF_CharData* pData = (CRF_CharData*)tempArray.GetAt(j);
   1056             if (m_pTempLine) {
   1057                 m_pTempLine->Add(pData);
   1058             }
   1059         }
   1060         tempArray.RemoveAll();
   1061     } else if(pObj->m_Type == PDFPAGE_IMAGE) {
   1062         CPDF_ImageObject* pImageObj = (CPDF_ImageObject* )pObj;
   1063         CRF_ImageData* pRFImage = (CRF_ImageData*)m_pReflowedPage->m_pMemoryPool->Alloc(sizeof(CRF_ImageData));
   1064         if (NULL == pRFImage) {
   1065             return;
   1066         }
   1067         pRFImage->m_pBitmap = NULL;
   1068         pRFImage->m_Type = CRF_Data::Image;
   1069         if (m_pTempLine) {
   1070             m_pTempLine->Add(pRFImage);
   1071         }
   1072         CPDF_Image *pImage = pImageObj->m_pImage;
   1073         if (!pImage->m_pDIBSource || !pImage->m_pMask) {
   1074             if(pImage->StartLoadDIBSource(m_pReflowedPage->GetFormResDict(pImageObj), m_pReflowedPage->m_pPDFPage->m_pResources, 0, 0, TRUE)) {
   1075                 pImage->Continue(NULL);
   1076             }
   1077         }
   1078         CFX_DIBSource* pDibSource = pImage->DetachBitmap();
   1079         if (pDibSource) {
   1080             pRFImage->m_pBitmap = pDibSource->Clone();
   1081             delete pDibSource;
   1082         }
   1083         CFX_DIBSource* pMask = pImage->DetachMask();
   1084         if (pMask) {
   1085             if (!pMask->IsAlphaMask()) {
   1086                 CFX_DIBitmap* pMaskBmp = pMask->Clone();
   1087                 pMaskBmp->ConvertFormat(FXDIB_8bppMask);
   1088                 pRFImage->m_pBitmap->MultiplyAlpha(pMaskBmp);
   1089                 delete pMaskBmp;
   1090             } else {
   1091                 pRFImage->m_pBitmap->MultiplyAlpha(pMask);
   1092             }
   1093             delete pMask;
   1094         }
   1095         CFX_FloatRect ObjBBox;
   1096         if(pObjMatrix) {
   1097             ObjBBox = pImageObj->GetBBox(pObjMatrix);
   1098         } else {
   1099             CFX_AffineMatrix matrix;
   1100             ObjBBox = pImageObj->GetBBox(&matrix);
   1101         }
   1102         pRFImage->m_Width = ObjBBox.Width();
   1103         pRFImage->m_Height = ObjBBox.Height();
   1104         pRFImage->m_PosX = 0;
   1105         pRFImage->m_PosY = 0;
   1106         CFX_AffineMatrix matrix(1, 0, 0, -1, 0, 0);
   1107         matrix.Concat(pImageObj->m_Matrix);
   1108         matrix.Concat(*pObjMatrix);
   1109         pRFImage->m_Matrix.Set(matrix.a == 0 ? 0 : matrix.a / FXSYS_fabs(matrix.a),
   1110                                matrix.b == 0 ? 0 : matrix.b / FXSYS_fabs(matrix.b),
   1111                                matrix.c == 0 ? 0 : matrix.c / FXSYS_fabs(matrix.c),
   1112                                matrix.d == 0 ? 0 : matrix.d / FXSYS_fabs(matrix.d), 0, 0);
   1113     } else if(pObj->m_Type == PDFPAGE_PATH) {
   1114     }
   1115 }
   1116 FX_FLOAT CPDF_LayoutProcessor_Reflow:: GetDatasWidth(int beginPos, int endpos)
   1117 {
   1118     if(endpos < beginPos || !m_pTempLine) {
   1119         return 0;
   1120     }
   1121     if(endpos > m_pTempLine->GetSize() - 1) {
   1122         endpos = m_pTempLine->GetSize() - 1;
   1123     }
   1124     CRF_Data* pBeginData = (*m_pTempLine)[beginPos];
   1125     CRF_Data* pEndData = (*m_pTempLine)[endpos];
   1126     return pEndData->m_PosX - pBeginData->m_PosX + pEndData->m_Width;
   1127 }
   1128 FX_WCHAR CPDF_LayoutProcessor_Reflow::GetPreChar()
   1129 {
   1130     if (NULL == m_pCurrLine) {
   1131         return -1;
   1132     }
   1133     int index = m_pCurrLine->GetSize() - 1;
   1134     CRF_CharData* pCharData = NULL;
   1135     while (index >= 0 && !pCharData) {
   1136         CRF_Data* pData = (*m_pCurrLine)[index];
   1137         if(pData->GetType() == CRF_Data::Text) {
   1138             pCharData = (CRF_CharData*)pData;
   1139         } else {
   1140             return -1;
   1141         }
   1142         index --;
   1143     }
   1144     if(m_pReflowedPage) {
   1145         index = m_pReflowedPage->m_pReflowed->GetSize() - 1;
   1146     }
   1147     while(!pCharData && index >= 0) {
   1148         CRF_Data* pData = (*m_pReflowedPage->m_pReflowed)[index];
   1149         if(pData->GetType() == CRF_Data::Text) {
   1150             pCharData = (CRF_CharData*)pData;
   1151         } else {
   1152             return -1;
   1153         }
   1154         index --;
   1155     }
   1156     if(pCharData) {
   1157         CFX_WideString str = pCharData->m_pCharState->m_pFont->UnicodeFromCharCode(pCharData->m_CharCode);
   1158         return str.GetAt(0);
   1159     }
   1160     return -1;
   1161 }
   1162 int CPDF_LayoutProcessor_Reflow::ProcessInsertObject(CPDF_TextObject* pObj, CFX_AffineMatrix formMatrix)
   1163 {
   1164     if(!pObj || !m_pPreObj || !m_pCurrLine) {
   1165         return 0;
   1166     }
   1167     if(m_pCurrLine->GetSize() == 0) {
   1168         return 0;
   1169     }
   1170     CPDF_TextObjectItem item;
   1171     int nItem = m_pPreObj->CountItems();
   1172     m_pPreObj->GetItemInfo(nItem - 1, &item);
   1173     FX_FLOAT last_pos = item.m_OriginX;
   1174     FX_FLOAT last_width = GetCharWidth(item.m_CharCode, m_pPreObj->GetFont()) * m_pPreObj->GetFontSize() / 1000;
   1175     last_width = FXSYS_fabs(last_width);
   1176     pObj->GetItemInfo(0, &item);
   1177     FX_FLOAT this_width = GetCharWidth(item.m_CharCode, pObj->GetFont()) * pObj->GetFontSize() / 1000;
   1178     this_width = FXSYS_fabs(this_width);
   1179     FX_FLOAT threshold = last_width > this_width ? last_width / 4 : this_width / 4;
   1180     CFX_AffineMatrix prev_matrix, prev_reverse;
   1181     m_pPreObj->GetTextMatrix(&prev_matrix);
   1182     prev_matrix.Concat(m_perMatrix);
   1183     prev_reverse.SetReverse(prev_matrix);
   1184     FX_FLOAT x = pObj->GetPosX(), y = pObj->GetPosY();
   1185     formMatrix.Transform(x, y);
   1186     prev_reverse.Transform(x, y);
   1187     FX_WCHAR preChar  = GetPreChar();
   1188     CFX_WideString wstrItem = pObj->GetFont()->UnicodeFromCharCode(item.m_CharCode);
   1189     FX_WCHAR curChar = wstrItem.GetAt(0);
   1190     if (FXSYS_fabs(y) > threshold * 2) {
   1191         if (preChar == L'-') {
   1192             return 3;
   1193         }
   1194         if (preChar != L' ') {
   1195             return 1;
   1196         }
   1197         return 2;
   1198     }
   1199     if ((x - last_pos - last_width) > threshold && curChar != L' ' && preChar != L' ') {
   1200         return 1;
   1201     }
   1202     return 0;
   1203 }
   1204 FX_INT32 CPDF_LayoutProcessor_Reflow::LogicPreObj(CPDF_TextObject* pObj)
   1205 {
   1206     CPDF_TextObject* pPreObj = m_pPreObj;
   1207     m_pPreObj = pObj;
   1208     if(!pObj || !pPreObj) {
   1209         return 0;
   1210     }
   1211     CPDF_TextObjectItem item;
   1212     pPreObj->GetItemInfo(pPreObj->CountItems() - 1, &item);
   1213     FX_FLOAT last_pos = item.m_OriginX;
   1214     FX_FLOAT last_width = pPreObj->GetFont()->GetCharWidthF(item.m_CharCode) * pPreObj->GetFontSize() / 1000;
   1215     last_width = FXSYS_fabs(last_width);
   1216     pObj->GetItemInfo(0, &item);
   1217     FX_FLOAT this_width = pObj->GetFont()->GetCharWidthF(item.m_CharCode) * pObj->GetFontSize() / 1000;
   1218     this_width = FXSYS_fabs(this_width);
   1219     FX_FLOAT threshold = last_width > this_width ? last_width / 4 : this_width / 4;
   1220     CFX_AffineMatrix prev_matrix, prev_reverse;
   1221     pPreObj->GetTextMatrix(&prev_matrix);
   1222     prev_reverse.SetReverse(prev_matrix);
   1223     FX_FLOAT x = pObj->GetPosX(), y = pObj->GetPosY();
   1224     prev_reverse.Transform(x, y);
   1225     CFX_WideString wstrItem = pObj->GetFont()->UnicodeFromCharCode(item.m_CharCode);
   1226     FX_WCHAR curChar = wstrItem.GetAt(0);
   1227     if (FXSYS_fabs(y) > threshold * 2) {
   1228         return 2;
   1229     }
   1230     FX_WCHAR preChar = 0;
   1231     if (FXSYS_fabs(last_pos + last_width - x) > threshold && curChar != L' ') {
   1232         return 1;
   1233     }
   1234     return 0;
   1235     m_pPreObj = pObj;
   1236     if(!pPreObj) {
   1237         return 0;
   1238     }
   1239     if(pPreObj->m_Type != pObj->m_Type) {
   1240         return 0;
   1241     }
   1242     CFX_FloatRect rcCurObj(pObj->m_Left, pObj->m_Bottom, pObj->m_Right, pObj->m_Top);
   1243     CFX_FloatRect rcPreObj(pPreObj->m_Left, pPreObj->m_Bottom, pPreObj->m_Right, pPreObj->m_Top);
   1244     if(pObj->m_Type == PDFPAGE_IMAGE) {
   1245         if(rcPreObj.Contains(rcCurObj)) {
   1246             return 2;
   1247         }
   1248         if(rcCurObj.Contains(rcPreObj)) {
   1249             return 2;
   1250         }
   1251         return 0;
   1252     }
   1253     if(pObj->m_Type == PDFPAGE_TEXT) {
   1254         if(!((rcPreObj.bottom > rcCurObj.top) || (rcPreObj.top < rcCurObj.bottom))) {
   1255             FX_FLOAT height = FX_MIN(rcPreObj.Height(), rcCurObj.Height());
   1256             if((rcCurObj.left - rcPreObj.right) > height / 3) {
   1257                 return 3;
   1258             }
   1259         }
   1260         if(FXSYS_fabs(rcPreObj.Width() - rcCurObj.Width()) >= 2 || FXSYS_fabs(rcPreObj.Height() - rcCurObj.Height()) >= 2 ) {
   1261             return 0;
   1262         }
   1263         CPDF_TextObject* pPreTextObj = (CPDF_TextObject*)pPreObj;
   1264         CPDF_TextObject* pCurTextObj = (CPDF_TextObject*)pObj;
   1265         int nPreCount = pPreTextObj->CountItems();
   1266         int nCurCount = pCurTextObj->CountItems();
   1267         if (nPreCount != nCurCount) {
   1268             return 0;
   1269         }
   1270         FX_BOOL bSame = TRUE;
   1271         for (int i = 0; i < nPreCount; i++) {
   1272             CPDF_TextObjectItem itemPer, itemCur;
   1273             pPreTextObj->GetItemInfo(i, &itemPer);
   1274             pCurTextObj->GetItemInfo(i, &itemCur);
   1275             if (itemCur.m_CharCode != itemPer.m_CharCode) {
   1276                 return 0;
   1277             }
   1278             if (itemCur.m_OriginX != itemPer.m_OriginX) {
   1279                 bSame = FALSE;
   1280             }
   1281             if (itemCur.m_OriginY != itemPer.m_OriginY) {
   1282                 bSame = FALSE;
   1283             }
   1284         }
   1285         if(rcPreObj.left == rcCurObj.left && rcPreObj.top == rcCurObj.top) {
   1286             return 1;
   1287         }
   1288         if(FXSYS_fabs(rcPreObj.left - rcCurObj.left) < rcPreObj.Width() / 3
   1289                 && FXSYS_fabs(rcPreObj.top - rcCurObj.top) < rcPreObj.Height() / 3) {
   1290             return 2;
   1291         }
   1292     }
   1293     return 0;
   1294 }
   1295 FX_BOOL CPDF_LayoutProcessor_Reflow::IsSameTextObject(CPDF_TextObject* pTextObj1, CPDF_TextObject* pTextObj2)
   1296 {
   1297     if (!pTextObj1 || !pTextObj2) {
   1298         return FALSE;
   1299     }
   1300     CFX_FloatRect rcPreObj(pTextObj2->m_Left, pTextObj2->m_Bottom, pTextObj2->m_Right, pTextObj2->m_Top);
   1301     CFX_FloatRect rcCurObj(pTextObj1->m_Left, pTextObj1->m_Bottom, pTextObj1->m_Right, pTextObj1->m_Top);
   1302     if (rcPreObj.IsEmpty() && rcCurObj.IsEmpty()) {
   1303         return FALSE;
   1304     }
   1305     if (!rcPreObj.IsEmpty() || !rcCurObj.IsEmpty()) {
   1306         rcPreObj.Intersect(rcCurObj);
   1307         if (rcPreObj.IsEmpty()) {
   1308             return FALSE;
   1309         }
   1310         if (FXSYS_fabs(rcPreObj.Width() - rcCurObj.Width()) > rcCurObj.Width() / 2) {
   1311             return FALSE;
   1312         }
   1313         if (pTextObj2->GetFontSize() != pTextObj1->GetFontSize()) {
   1314             return FALSE;
   1315         }
   1316     }
   1317     int nPreCount = pTextObj2->CountItems();
   1318     int nCurCount = pTextObj1->CountItems();
   1319     if (nPreCount != nCurCount) {
   1320         return FALSE;
   1321     }
   1322     for (int i = 0; i < nPreCount; i++) {
   1323         CPDF_TextObjectItem itemPer, itemCur;
   1324         pTextObj2->GetItemInfo(i, &itemPer);
   1325         pTextObj1->GetItemInfo(i, &itemCur);
   1326         if (itemCur.m_CharCode != itemPer.m_CharCode) {
   1327             return FALSE;
   1328         }
   1329     }
   1330     return TRUE;
   1331 }
   1332 void CPDF_LayoutProcessor_Reflow::ProcessTextObject(CPDF_TextObject *pTextObj, FX_FLOAT reflowWidth, CFX_AffineMatrix objMatrix)
   1333 {
   1334     if(reflowWidth < 0 || !m_pCurrLine || !m_pTempLine) {
   1335         return;
   1336     }
   1337     if(IsSameTextObject(pTextObj, m_pPreObj)) {
   1338         return;
   1339     }
   1340     CPDF_PageObject* pPreObj = m_pPreObj;
   1341     FX_INT32 logic = ProcessInsertObject(pTextObj, objMatrix);
   1342     m_pPreObj = pTextObj;
   1343     m_perMatrix.Copy(objMatrix);
   1344     int size = m_pTempLine->GetSize();
   1345     int curs = m_pCurrLine->GetSize();
   1346     CreateRFData(pTextObj);
   1347     size = m_pTempLine->GetSize();
   1348     int reds = m_pReflowedPage->m_pReflowed->GetSize();
   1349     if(size == 0) {
   1350         return;
   1351     }
   1352     if(logic == 1) {
   1353         m_fCurrLineWidth += pTextObj->GetBBox(&objMatrix).Height() / 3;
   1354     } else if(logic == 3 && curs) {
   1355         m_fCurrLineWidth -= (*m_pCurrLine)[curs - 1]->m_Width;
   1356         m_pCurrLine->Delete(curs - 1);
   1357     }
   1358     int beginPos = 0, endPos = m_pTempLine->GetSize() - 1;
   1359     while(beginPos <= endPos) {
   1360         int tempBeginPos = beginPos;
   1361         int tempEndPos = endPos;
   1362         FX_FLOAT all_width = GetDatasWidth( beginPos, endPos);
   1363         if(all_width < reflowWidth - m_fCurrLineWidth) {
   1364             CRF_CharData* pBeginData = (CRF_CharData*)(*m_pTempLine)[beginPos];
   1365             CFX_AffineMatrix matrix(1, 0, 0, 1, -pBeginData->m_PosX + m_fCurrLineWidth, -pBeginData->m_PosY);
   1366             Transform(&matrix, m_pTempLine, beginPos, endPos - beginPos + 1);
   1367             AddTemp2CurrLine(beginPos, endPos - beginPos + 1);
   1368             m_pTempLine->RemoveAll();
   1369             return;
   1370         }
   1371         int	midPos ;
   1372         if(tempBeginPos >= tempEndPos && tempEndPos != 0) {
   1373             midPos = tempEndPos;
   1374         } else {
   1375             while (tempBeginPos < tempEndPos ) {
   1376                 midPos = (tempEndPos - tempBeginPos) / 2 + tempBeginPos;
   1377                 if(midPos == tempBeginPos || midPos == tempEndPos) {
   1378                     break;
   1379                 }
   1380                 FX_FLOAT w = GetDatasWidth( beginPos, midPos);
   1381                 if(w < reflowWidth - m_fCurrLineWidth) {
   1382                     tempBeginPos = midPos;
   1383                 } else {
   1384                     tempEndPos = midPos;
   1385                 }
   1386             }
   1387             midPos = tempBeginPos;
   1388             if(midPos == 0) {
   1389                 FX_FLOAT w = GetDatasWidth( beginPos, 1);
   1390                 if(w > reflowWidth - m_fCurrLineWidth) {
   1391                     midPos = -1;
   1392                 }
   1393             }
   1394         }
   1395         if(midPos == -1) {
   1396             int count = m_pCurrLine->GetSize();
   1397             if(count == 0) {
   1398                 midPos = 0;
   1399             }
   1400         }
   1401         int f = -1;
   1402         int i = 0;
   1403         for(i = midPos; i >= beginPos; i--) {
   1404             CRF_CharData* pData = (CRF_CharData*)(*m_pTempLine)[i];
   1405             CFX_WideString Wstr = pData->m_pCharState->m_pFont->UnicodeFromCharCode(pData->m_CharCode);
   1406             FX_WCHAR cha = Wstr.GetAt(0);
   1407             if(i < m_pTempLine->GetSize() - 1) {
   1408                 CRF_CharData* pNextData = (CRF_CharData*)(*m_pTempLine)[i + 1];
   1409                 if(pNextData->m_PosX - (pData->m_PosX + pData->m_Width) >= pData->m_Height / 4) {
   1410                     f = i;
   1411                     i++;
   1412                 }
   1413             }
   1414             if(f == -1) {
   1415                 if(IsCanBreakAfter((FX_DWORD)cha)) {
   1416                     f = i;
   1417                     i++;
   1418                 } else if(IsCanBreakBefore((FX_DWORD)cha)) {
   1419                     f = i - 1;
   1420                     if(f < beginPos) {
   1421                         f = -1;
   1422                     }
   1423                 }
   1424             }
   1425             if(f != -1) {
   1426                 CRF_CharData* pBeginData = (CRF_CharData*)(*m_pTempLine)[beginPos];
   1427                 CFX_AffineMatrix matrix(1, 0, 0, 1, -pBeginData->m_PosX + m_fCurrLineWidth, -pBeginData->m_PosY);
   1428                 Transform(&matrix, m_pTempLine, beginPos, f - beginPos + 1);
   1429                 CRF_Data* pData = (*m_pTempLine)[0];
   1430                 AddTemp2CurrLine(beginPos, f - beginPos + 1);
   1431                 beginPos = i;
   1432                 FinishedCurrLine();
   1433                 f = 1;
   1434                 break;
   1435             }
   1436         }
   1437         if(f == -1 && i < beginPos) {
   1438             if( m_pCurrLine->GetSize()) {
   1439                 int count = m_pCurrLine->GetSize();
   1440                 f = -1;
   1441                 for(int i = count - 1; i >= 0; i--) {
   1442                     CRF_Data* pData = (*m_pCurrLine)[i];
   1443                     if(pData->GetType() != CRF_Data::Text) {
   1444                         f = i + 1;
   1445                     } else {
   1446                         CRF_CharData* pCharData = (CRF_CharData*)pData;
   1447                         CFX_WideString Wstr = pCharData->m_pCharState->m_pFont->UnicodeFromCharCode(pCharData->m_CharCode);
   1448                         FX_WCHAR cha = Wstr.GetAt(0);
   1449                         if(IsCanBreakAfter(cha)) {
   1450                             f = i + 1;
   1451                             i++;
   1452                         } else if(IsCanBreakBefore(cha)) {
   1453                             f = i;
   1454                         }
   1455                         if(f == 0) {
   1456                             f = -1;
   1457                         }
   1458                     }
   1459                     if(f != -1) {
   1460                         FinishedCurrLine();
   1461                         if(f < count) {
   1462                             int reflowdCount = m_pReflowedPage->m_pReflowed->GetSize();
   1463                             int pos = reflowdCount + f - count;
   1464                             CRF_CharData* pData = (CRF_CharData*)(*m_pReflowedPage->m_pReflowed)[pos];
   1465                             CFX_AffineMatrix matrix(1, 0, 0, 1, -pData->m_PosX + m_fCurrLineWidth, -pData->m_PosY);
   1466                             Transform(&matrix, m_pReflowedPage->m_pReflowed, pos, reflowdCount - pos);
   1467                             for(int j = pos; j < reflowdCount; j++) {
   1468                                 AddData2CurrLine((*m_pReflowedPage->m_pReflowed)[j]);
   1469                             }
   1470                             m_pReflowedPage->m_pReflowed->Delete(pos, count - f);
   1471                             if(logic == 3) {
   1472                                 m_fCurrLineWidth += pTextObj->GetBBox(&objMatrix).Height() / 3;
   1473                             }
   1474                         }
   1475                         break;
   1476                     }
   1477                 }
   1478             }
   1479             if(f == -1) {
   1480                 CRF_CharData* pData = (CRF_CharData*)(*m_pTempLine)[beginPos];
   1481                 CFX_AffineMatrix matrix(1, 0, 0, 1, -pData->m_PosX + m_fCurrLineWidth, -pData->m_PosY);
   1482                 if(beginPos == midPos) {
   1483                     Transform(&matrix, pData);
   1484                     FX_RECT rect;
   1485                     pData->m_pCharState->m_pFont->GetFontBBox(rect);
   1486                     FX_FLOAT* pmatrix = pTextObj->m_TextState.GetMatrix();
   1487                     CFX_AffineMatrix textMatrix(pmatrix[0], pmatrix[1], pmatrix[2], pmatrix[3], 0, 0);
   1488                     FX_FLOAT width = pData->m_Height * (rect.right - rect.left) / 1000;
   1489                     FX_FLOAT f = (reflowWidth - m_fCurrLineWidth) / width;
   1490                     pData->m_PosY *= f;
   1491                     pData->m_Width *= f;
   1492                     pData->m_Height *= f;
   1493                     pData->m_pCharState = GetCharState(pData->m_pCharState->m_pTextObj, pData->m_pCharState->m_pFont, pData->m_Height, pData->m_pCharState->m_Color);
   1494                     AddData2CurrLine(pData);
   1495                 } else {
   1496                     for(int m = beginPos; m <= midPos; m++) {
   1497                         CRF_CharData* pData = (CRF_CharData*)(*m_pTempLine)[m];
   1498                         Transform(&matrix, pData);
   1499                         AddData2CurrLine(pData);
   1500                     }
   1501                 }
   1502                 FinishedCurrLine();
   1503                 beginPos = midPos + 1;
   1504             }
   1505         }
   1506     }
   1507     m_pTempLine->RemoveAll();
   1508     return;
   1509 }
   1510 void CPDF_LayoutProcessor_Reflow::ProcessUnitaryObjs(CPDF_PageObjects *pObjs, FX_FLOAT reflowWidth, CFX_AffineMatrix objMatrix)
   1511 {
   1512     if(!pObjs) {
   1513         return;
   1514     }
   1515     CFX_FloatRect ObjBBox = pObjs->CalcBoundingBox();
   1516     objMatrix.TransformRect(ObjBBox);
   1517     FX_FLOAT ObjWidth = ObjBBox.Width();
   1518     FX_FLOAT ObjHeight = ObjBBox.Height();
   1519     CFX_AffineMatrix matrix;
   1520     if(ObjWidth <= reflowWidth - m_fCurrLineWidth) {
   1521         matrix.Set(1, 0, 0, 1, m_fCurrLineWidth , 0);
   1522     } else if(ObjWidth <= reflowWidth) {
   1523         FinishedCurrLine();
   1524         matrix.Set(1, 0, 0, 1, 0, 0);
   1525     } else {
   1526         FinishedCurrLine();
   1527         FX_FLOAT f = reflowWidth / ObjWidth ;
   1528         matrix.Set(f, 0, 0, f, 0, 0);
   1529     }
   1530     CFX_AffineMatrix tempMatrix = matrix;
   1531     matrix.Concat(objMatrix);
   1532     FX_POSITION pos = pObjs->GetFirstObjectPosition();
   1533     while(pos) {
   1534         CPDF_PageObject* pObj = pObjs->GetNextObject(pos);
   1535         if(pObj->m_Type == PDFPAGE_TEXT) {
   1536             FX_INT32 ret = LogicPreObj((CPDF_TextObject*)pObj);
   1537             if(ret == 1 || ret == 2) {
   1538                 continue;
   1539             }
   1540         }
   1541         CreateRFData(pObj, &matrix);
   1542     }
   1543     if (m_pTempLine) {
   1544         Transform(&tempMatrix, m_pTempLine, 0, m_pTempLine->GetSize());
   1545         AddTemp2CurrLine(0, m_pTempLine->GetSize());
   1546         m_pTempLine->RemoveAll();
   1547     }
   1548 }
   1549 void CPDF_LayoutProcessor_Reflow::ProcessPathObject(CPDF_PathObject *pObj, FX_FLOAT reflowWidth)
   1550 {
   1551 }
   1552