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