// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "../../../include/fpdfapi/fpdf_page.h"
#include "../../../include/fpdfapi/fpdf_module.h"
#include "pageint.h"
CPDF_PageObject* CPDF_PageObject::Create(int type)
{
    switch (type) {
        case PDFPAGE_TEXT:
            return new CPDF_TextObject;
        case PDFPAGE_IMAGE:
            return new CPDF_ImageObject;
        case PDFPAGE_PATH:
            return new CPDF_PathObject;
        case PDFPAGE_SHADING:
            return new CPDF_ShadingObject;
        case PDFPAGE_FORM:
            return new CPDF_FormObject;
    }
    return NULL;
}
CPDF_PageObject::~CPDF_PageObject()
{
}
CPDF_PageObject* CPDF_PageObject::Clone() const
{
    CPDF_PageObject* pObj = Create(m_Type);
    pObj->Copy(this);
    return pObj;
}
void CPDF_PageObject::Copy(const CPDF_PageObject* pSrc)
{
    if (m_Type != pSrc->m_Type) {
        return;
    }
    CopyData(pSrc);
    CopyStates(*pSrc);
    m_Left = pSrc->m_Left;
    m_Right = pSrc->m_Right;
    m_Top = pSrc->m_Top;
    m_Bottom = pSrc->m_Bottom;
}
void CPDF_PageObject::AppendClipPath(CPDF_Path path, int type, FX_BOOL bAutoMerge)
{
    m_ClipPath.AppendPath(path, type, bAutoMerge);
}
void CPDF_PageObject::CopyClipPath(CPDF_PageObject* pObj)
{
    m_ClipPath = pObj->m_ClipPath;
}
void CPDF_PageObject::RemoveClipPath()
{
    m_ClipPath.SetNull();
}
void CPDF_PageObject::RecalcBBox()
{
    switch (m_Type) {
        case PDFPAGE_TEXT:
            ((CPDF_TextObject*)this)->RecalcPositionData();
            break;
        case PDFPAGE_PATH:
            ((CPDF_PathObject*)this)->CalcBoundingBox();
            break;
        case PDFPAGE_SHADING:
            ((CPDF_ShadingObject*)this)->CalcBoundingBox();
            break;
    }
}
void CPDF_PageObject::TransformClipPath(CFX_AffineMatrix& matrix)
{
    if (m_ClipPath.IsNull()) {
        return;
    }
    m_ClipPath.GetModify();
    m_ClipPath.Transform(matrix);
}
void CPDF_PageObject::TransformGeneralState(CFX_AffineMatrix& matrix)
{
    if(m_GeneralState.IsNull()) {
        return;
    }
    CPDF_GeneralStateData* pGS = m_GeneralState.GetModify();
    pGS->m_Matrix.Concat(matrix);
}
FX_RECT CPDF_PageObject::GetBBox(const CFX_AffineMatrix* pMatrix) const
{
    CFX_FloatRect rect(m_Left, m_Bottom, m_Right, m_Top);
    if (pMatrix) {
        pMatrix->TransformRect(rect);
    }
    return rect.GetOutterRect();
}

CPDF_TextObject::CPDF_TextObject()
    : m_PosX(0),
      m_PosY(0),
      m_nChars(0),
      m_pCharCodes(nullptr),
      m_pCharPos(nullptr)
{
    m_Type = PDFPAGE_TEXT;
}

CPDF_TextObject::~CPDF_TextObject()
{
    if (m_nChars > 1 && m_pCharCodes) {
        FX_Free(m_pCharCodes);
    }
    if (m_pCharPos) {
        FX_Free(m_pCharPos);
    }
}

void CPDF_TextObject::GetItemInfo(int index, CPDF_TextObjectItem* pInfo) const
{
    pInfo->m_CharCode =
        m_nChars == 1 ? (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[index];
    pInfo->m_OriginX = index ? m_pCharPos[index - 1] : 0;
    pInfo->m_OriginY = 0;
    if (pInfo->m_CharCode == -1) {
        return;
    }
    CPDF_Font* pFont = m_TextState.GetFont();
    if (pFont->GetFontType() != PDFFONT_CIDFONT) {
        return;
    }
    if (!((CPDF_CIDFont*)pFont)->IsVertWriting()) {
        return;
    }
    FX_WORD CID = ((CPDF_CIDFont*)pFont)->CIDFromCharCode(pInfo->m_CharCode);
    pInfo->m_OriginY = pInfo->m_OriginX;
    pInfo->m_OriginX = 0;
    short vx, vy;
    ((CPDF_CIDFont*)pFont)->GetVertOrigin(CID, vx, vy);
    FX_FLOAT fontsize = m_TextState.GetFontSize();
    pInfo->m_OriginX -= fontsize * vx / 1000;
    pInfo->m_OriginY -= fontsize * vy / 1000;
}

int CPDF_TextObject::CountChars() const
{
    if (m_nChars == 1) {
        return 1;
    }
    int count = 0;
    for (int i = 0; i < m_nChars; ++i)
        if (m_pCharCodes[i] != (FX_DWORD) - 1) {
            ++count;
        }
    return count;
}

void CPDF_TextObject::GetCharInfo(int index,
                                  FX_DWORD& charcode,
                                  FX_FLOAT& kerning) const
{
    if (m_nChars == 1) {
        charcode = (FX_DWORD)(uintptr_t)m_pCharCodes;
        kerning = 0;
        return;
    }
    int count = 0;
    for (int i = 0; i < m_nChars; ++i) {
        if (m_pCharCodes[i] != (FX_DWORD) - 1) {
            if (count == index) {
                charcode = m_pCharCodes[i];
                if (i == m_nChars - 1 ||
                    m_pCharCodes[i + 1] != (FX_DWORD) - 1) {
                    kerning = 0;
                } else {
                    kerning = m_pCharPos[i];
                }
                return;
            }
            ++count;
        }
    }
}

void CPDF_TextObject::GetCharInfo(int index, CPDF_TextObjectItem* pInfo) const
{
    if (m_nChars == 1) {
        GetItemInfo(0, pInfo);
        return;
    }
    int count = 0;
    for (int i = 0; i < m_nChars; ++i) {
        FX_DWORD charcode = m_pCharCodes[i];
        if (charcode == (FX_DWORD) - 1) {
            continue;
        }
        if (count == index) {
            GetItemInfo(i, pInfo);
            break;
        }
        ++count;
    }
}

void CPDF_TextObject::CopyData(const CPDF_PageObject* pSrc)
{
    const CPDF_TextObject* pSrcObj = (const CPDF_TextObject*)pSrc;
    if (m_nChars > 1 && m_pCharCodes) {
        FX_Free(m_pCharCodes);
        m_pCharCodes = nullptr;
    }
    if (m_pCharPos) {
        FX_Free(m_pCharPos);
        m_pCharPos = nullptr;
    }
    m_nChars = pSrcObj->m_nChars;
    if (m_nChars > 1) {
        m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars);
        m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1);
        for (int i = 0; i < m_nChars; ++i) {
            m_pCharCodes[i] = pSrcObj->m_pCharCodes[i];
        }
        for (int i = 0; i < m_nChars - 1; ++i) {
            m_pCharPos[i] = pSrcObj->m_pCharPos[i];
        }
    } else {
        m_pCharCodes = pSrcObj->m_pCharCodes;
    }
    m_PosX = pSrcObj->m_PosX;
    m_PosY = pSrcObj->m_PosY;
}

void CPDF_TextObject::GetTextMatrix(CFX_AffineMatrix* pMatrix) const
{
    FX_FLOAT* pTextMatrix = m_TextState.GetMatrix();
    pMatrix->Set(pTextMatrix[0],
                 pTextMatrix[2],
                 pTextMatrix[1],
                 pTextMatrix[3],
                 m_PosX,
                 m_PosY);
}

void CPDF_TextObject::SetSegments(const CFX_ByteString* pStrs,
                                  FX_FLOAT* pKerning,
                                  int nsegs)
{
    if (m_nChars > 1 && m_pCharCodes) {
        FX_Free(m_pCharCodes);
        m_pCharCodes = nullptr;
    }
    if (m_pCharPos) {
        FX_Free(m_pCharPos);
        m_pCharPos = nullptr;
    }
    CPDF_Font* pFont = m_TextState.GetFont();
    m_nChars = 0;
    for (int i = 0; i < nsegs; ++i) {
        m_nChars += pFont->CountChar(pStrs[i], pStrs[i].GetLength());
    }
    m_nChars += nsegs - 1;
    if (m_nChars > 1) {
        m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars);
        m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1);
        int index = 0;
        for (int i = 0; i < nsegs; ++i) {
            const FX_CHAR* segment = pStrs[i];
            int offset = 0, len = pStrs[i].GetLength();
            while (offset < len) {
                m_pCharCodes[index++] =
                    pFont->GetNextChar(segment, len, offset);
            }
            if (i != nsegs - 1) {
                m_pCharPos[index - 1] = pKerning[i];
                m_pCharCodes[index++] = (FX_DWORD) - 1;
            }
        }
    } else {
        int offset = 0;
        m_pCharCodes =
            (FX_DWORD*)(uintptr_t)pFont->GetNextChar(pStrs[0],
                                                     pStrs[0].GetLength(),
                                                     offset);
    }
}

void CPDF_TextObject::SetText(const CFX_ByteString& str)
{
    SetSegments(&str, nullptr, 1);
    RecalcPositionData();
}

void CPDF_TextObject::SetEmpty()
{
    if (m_nChars > 1 && m_pCharCodes) {
        FX_Free(m_pCharCodes);
    }
    if (m_nChars > 1 && m_pCharPos) {
        FX_Free(m_pCharPos);
    }
    m_nChars = 0;
    m_pCharCodes = nullptr;
    m_pCharPos = nullptr;
    m_Left = m_Right = m_PosX;
    m_Top = m_Bottom = m_PosY;
}

void CPDF_TextObject::SetText(CFX_ByteString* pStrs,
                              FX_FLOAT* pKerning,
                              int nSegs)
{
    SetSegments(pStrs, pKerning, nSegs);
    RecalcPositionData();
}

void CPDF_TextObject::SetText(int nChars,
                              FX_DWORD* pCharCodes,
                              FX_FLOAT* pKernings)
{
    if (m_nChars > 1 && m_pCharCodes) {
        FX_Free(m_pCharCodes);
        m_pCharCodes = nullptr;
    }
    if (m_pCharPos) {
        FX_Free(m_pCharPos);
        m_pCharPos = nullptr;
    }
    int nKernings = 0;
    int i;
    for (i = 0; i < nChars - 1; ++i) {
        if (pKernings[i] != 0) {
            ++nKernings;
        }
    }
    m_nChars = nChars + nKernings;
    if (m_nChars > 1) {
        m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars);
        m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1);
        for (int i = 0, index = 0; i < nChars; ++i) {
            m_pCharCodes[index++] = pCharCodes[i];
            if (pKernings[i] != 0 && i != nChars - 1) {
                m_pCharCodes[index] = (FX_DWORD) - 1;
                m_pCharPos[index - 1] = pKernings[i];
                ++index;
            }
        }
    } else {
        m_pCharCodes = (FX_DWORD*)(uintptr_t)pCharCodes[0];
    }
    RecalcPositionData();
}

FX_FLOAT CPDF_TextObject::GetCharWidth(FX_DWORD charcode) const
{
    FX_FLOAT fontsize = m_TextState.GetFontSize() / 1000;
    CPDF_Font* pFont = m_TextState.GetFont();
    FX_BOOL bVertWriting = FALSE;
    CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
    if (pCIDFont) {
        bVertWriting = pCIDFont->IsVertWriting();
    }
    if (!bVertWriting)
        return pFont->GetCharWidthF(charcode, 0) * fontsize;

    FX_WORD CID = pCIDFont->CIDFromCharCode(charcode);
    return pCIDFont->GetVertWidth(CID) * fontsize;
}

FX_FLOAT CPDF_TextObject::GetSpaceCharWidth() const
{
    CPDF_Font* pFont = m_TextState.GetFont();
    FX_DWORD charCode = m_TextState.GetFont()->CharCodeFromUnicode(32);
    if (charCode != (FX_DWORD) - 1) {
        return GetCharWidth(charCode);
    }
    FX_FLOAT fontSize = m_TextState.GetFontSize() / 4000.0f;
    FX_BOOL bVertWriting = FALSE;
    CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
    if (pCIDFont) {
        bVertWriting = pCIDFont->IsVertWriting();
    }
    FX_RECT fontRect;
    pFont->GetFontBBox(fontRect);
    fontSize *= bVertWriting ?
        (FX_FLOAT)fontRect.Height() : (FX_FLOAT)fontRect.Width();
    return fontSize;
}

void CPDF_TextObject::GetCharRect(int index, CFX_FloatRect& rect) const
{
    CPDF_Font* pFont = m_TextState.GetFont();
    FX_BOOL bVertWriting = FALSE;
    CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
    if (pCIDFont) {
        bVertWriting = pCIDFont->IsVertWriting();
    }
    FX_FLOAT fontsize = m_TextState.GetFontSize() / 1000;
    int count = 0;
    for (int i = 0; i < m_nChars; ++i) {
        FX_DWORD charcode = m_nChars == 1 ?
            (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[i];
        if (charcode == (FX_DWORD) - 1) {
            continue;
        }
        if (count != index) {
            ++count;
            continue;
        }
        FX_FLOAT curpos = i > 0 ? m_pCharPos[i - 1] : 0;
        FX_RECT char_rect;
        pFont->GetCharBBox(charcode, char_rect, 0);
        if (!bVertWriting) {
            rect.left = curpos + char_rect.left * fontsize;
            rect.right = curpos + char_rect.right * fontsize;
            rect.top = char_rect.top * fontsize;
            rect.bottom = char_rect.bottom * fontsize;
        } else {
            FX_WORD CID = pCIDFont->CIDFromCharCode(charcode);
            short vx, vy;
            pCIDFont->GetVertOrigin(CID, vx, vy);
            char_rect.left -= vx;
            char_rect.right -= vx;
            char_rect.top -= vy;
            char_rect.bottom -= vy;
            rect.left = char_rect.left * fontsize;
            rect.right = char_rect.right * fontsize;
            rect.top = curpos + char_rect.top * fontsize;
            rect.bottom = curpos + char_rect.bottom * fontsize;
        }
        return;
    }
}

void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX,
                                       FX_FLOAT* pTextAdvanceY,
                                       FX_FLOAT horz_scale,
                                       int level)
{
    FX_FLOAT curpos = 0;
    FX_FLOAT min_x = 10000 * 1.0f;
    FX_FLOAT max_x = -10000 * 1.0f;
    FX_FLOAT min_y = 10000 * 1.0f;
    FX_FLOAT max_y = -10000 * 1.0f;
    CPDF_Font* pFont = m_TextState.GetFont();
    FX_BOOL bVertWriting = FALSE;
    CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
    if (pCIDFont) {
        bVertWriting = pCIDFont->IsVertWriting();
    }
    FX_FLOAT fontsize = m_TextState.GetFontSize();
    for (int i = 0; i < m_nChars; ++i) {
        FX_DWORD charcode = m_nChars == 1 ?
            (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[i];
        if (charcode == (FX_DWORD) - 1) {
            curpos -= FXSYS_Mul(m_pCharPos[i - 1], fontsize) / 1000;
            continue;
        }
        if (i) {
            m_pCharPos[i - 1] = curpos;
        }
        FX_RECT char_rect;
        pFont->GetCharBBox(charcode, char_rect, level);
        FX_FLOAT charwidth;
        if (!bVertWriting) {
            if (min_y > char_rect.top) {
                min_y = (FX_FLOAT)char_rect.top;
            }
            if (max_y < char_rect.top) {
                max_y = (FX_FLOAT)char_rect.top;
            }
            if (min_y > char_rect.bottom) {
                min_y = (FX_FLOAT)char_rect.bottom;
            }
            if (max_y < char_rect.bottom) {
                max_y = (FX_FLOAT)char_rect.bottom;
            }
            FX_FLOAT char_left = curpos + char_rect.left * fontsize / 1000;
            FX_FLOAT char_right = curpos + char_rect.right * fontsize / 1000;
            if (min_x > char_left) {
                min_x = char_left;
            }
            if (max_x < char_left) {
                max_x = char_left;
            }
            if (min_x > char_right) {
                min_x = char_right;
            }
            if (max_x < char_right) {
                max_x = char_right;
            }
            charwidth = pFont->GetCharWidthF(charcode, level) * fontsize / 1000;
        } else {
            FX_WORD CID = pCIDFont->CIDFromCharCode(charcode);
            short vx;
            short vy;
            pCIDFont->GetVertOrigin(CID, vx, vy);
            char_rect.left -= vx;
            char_rect.right -= vx;
            char_rect.top -= vy;
            char_rect.bottom -= vy;
            if (min_x > char_rect.left) {
                min_x = (FX_FLOAT)char_rect.left;
            }
            if (max_x < char_rect.left) {
                max_x = (FX_FLOAT)char_rect.left;
            }
            if (min_x > char_rect.right) {
                min_x = (FX_FLOAT)char_rect.right;
            }
            if (max_x < char_rect.right) {
                max_x = (FX_FLOAT)char_rect.right;
            }
            FX_FLOAT char_top = curpos + char_rect.top * fontsize / 1000;
            FX_FLOAT char_bottom = curpos + char_rect.bottom * fontsize / 1000;
            if (min_y > char_top) {
                min_y = char_top;
            }
            if (max_y < char_top) {
                max_y = char_top;
            }
            if (min_y > char_bottom) {
                min_y = char_bottom;
            }
            if (max_y < char_bottom) {
                max_y = char_bottom;
            }
            charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000;
        }
        curpos += charwidth;
        if (charcode == ' ' && (!pCIDFont || pCIDFont->GetCharSize(32) == 1)) {
            curpos += m_TextState.GetObject()->m_WordSpace;
        }
        curpos += m_TextState.GetObject()->m_CharSpace;
    }
    if (bVertWriting) {
        if (pTextAdvanceX) {
            *pTextAdvanceX = 0;
        }
        if (pTextAdvanceY) {
            *pTextAdvanceY = curpos;
        }
        min_x = min_x * fontsize / 1000;
        max_x = max_x * fontsize / 1000;
    } else {
        if (pTextAdvanceX) {
            *pTextAdvanceX = FXSYS_Mul(curpos, horz_scale);
        }
        if (pTextAdvanceY) {
            *pTextAdvanceY = 0;
        }
        min_y = min_y * fontsize / 1000;
        max_y = max_y * fontsize / 1000;
    }
    CFX_AffineMatrix matrix;
    GetTextMatrix(&matrix);
    m_Left = min_x;
    m_Right = max_x;
    m_Bottom = min_y;
    m_Top = max_y;
    matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom);
    int textmode = m_TextState.GetObject()->m_TextMode;
    if (textmode == 1 || textmode == 2 || textmode == 5 || textmode == 6) {
        FX_FLOAT half_width = m_GraphState.GetObject()->m_LineWidth / 2;
        m_Left -= half_width;
        m_Right += half_width;
        m_Top += half_width;
        m_Bottom -= half_width;
    }
}

void CPDF_TextObject::CalcCharPos(FX_FLOAT* pPosArray) const
{
    CPDF_Font* pFont = m_TextState.GetFont();
    FX_BOOL bVertWriting = FALSE;
    CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
    if (pCIDFont) {
        bVertWriting = pCIDFont->IsVertWriting();
    }
    FX_FLOAT fontsize = m_TextState.GetFontSize();
    for (int i = 0, index = 0; i < m_nChars; ++i) {
        FX_DWORD charcode = m_nChars == 1 ?
            (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[i];
        if (charcode == (FX_DWORD) - 1) {
            continue;
        }
        pPosArray[index++] = i ? m_pCharPos[i - 1] : 0;
        FX_FLOAT charwidth;
        if (bVertWriting) {
            FX_WORD CID = pCIDFont->CIDFromCharCode(charcode);
            charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000;
        } else {
            charwidth = pFont->GetCharWidthF(charcode) * fontsize / 1000;
        }
        pPosArray[index] = pPosArray[index - 1] + charwidth;
        index++;
    }
}

void CPDF_TextObject::Transform(const CFX_AffineMatrix& matrix)
{
    m_TextState.GetModify();
    CFX_AffineMatrix text_matrix;
    GetTextMatrix(&text_matrix);
    text_matrix.Concat(matrix);
    FX_FLOAT* pTextMatrix = m_TextState.GetMatrix();
    pTextMatrix[0] = text_matrix.GetA();
    pTextMatrix[1] = text_matrix.GetC();
    pTextMatrix[2] = text_matrix.GetB();
    pTextMatrix[3] = text_matrix.GetD();
    m_PosX = text_matrix.GetE();
    m_PosY = text_matrix.GetF();
    CalcPositionData(nullptr, nullptr, 0);
}

void CPDF_TextObject::SetPosition(FX_FLOAT x, FX_FLOAT y)
{
    FX_FLOAT dx = x - m_PosX;
    FX_FLOAT dy = y - m_PosY;
    m_PosX = x;
    m_PosY = y;
    m_Left += dx;
    m_Right += dx;
    m_Top += dy;
    m_Bottom += dy;
}

void CPDF_TextObject::SetData(int nChars,
                              FX_DWORD* pCharCodes,
                              FX_FLOAT* pCharPos,
                              FX_FLOAT x,
                              FX_FLOAT y)
{
    ASSERT(m_nChars == 0);
    m_nChars = nChars;
    m_PosX = x;
    m_PosY = y;
    if (nChars == 0) {
        return;
    }
    if (nChars == 1) {
        m_pCharCodes = (FX_DWORD*)(uintptr_t) * pCharCodes;
    } else {
        m_pCharCodes = FX_Alloc(FX_DWORD, nChars);
        FXSYS_memcpy(m_pCharCodes, pCharCodes, sizeof(FX_DWORD)*nChars);
        m_pCharPos = FX_Alloc(FX_FLOAT, nChars - 1);
        FXSYS_memcpy(m_pCharPos, pCharPos, sizeof(FX_FLOAT) * (nChars - 1));
    }
    RecalcPositionData();
}

void CPDF_TextObject::SetTextState(CPDF_TextState TextState)
{
    m_TextState = TextState;
    CalcPositionData(nullptr, nullptr, 0);
}

CPDF_ShadingObject::CPDF_ShadingObject()
{
    m_pShading = NULL;
    m_Type = PDFPAGE_SHADING;
}
CPDF_ShadingObject::~CPDF_ShadingObject()
{
}
void CPDF_ShadingObject::CopyData(const CPDF_PageObject* pSrc)
{
    CPDF_ShadingObject* pSrcObj = (CPDF_ShadingObject*)pSrc;
    m_pShading = pSrcObj->m_pShading;
    if (m_pShading && m_pShading->m_pDocument) {
        CPDF_DocPageData* pDocPageData = m_pShading->m_pDocument->GetPageData();
        m_pShading = (CPDF_ShadingPattern*)pDocPageData->GetPattern(m_pShading->m_pShadingObj, m_pShading->m_bShadingObj, &m_pShading->m_ParentMatrix);
    }
    m_Matrix = pSrcObj->m_Matrix;
}
void CPDF_ShadingObject::Transform(const CFX_AffineMatrix& matrix)
{
    if (!m_ClipPath.IsNull()) {
        m_ClipPath.GetModify();
        m_ClipPath.Transform(matrix);
    }
    m_Matrix.Concat(matrix);
    if (!m_ClipPath.IsNull()) {
        CalcBoundingBox();
    } else {
        matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom);
    }
}
void CPDF_ShadingObject::CalcBoundingBox()
{
    if (m_ClipPath.IsNull()) {
        return;
    }
    CFX_FloatRect rect = m_ClipPath.GetClipBox();
    m_Left = rect.left;
    m_Bottom = rect.bottom;
    m_Right = rect.right;
    m_Top = rect.top;
}
CPDF_FormObject::~CPDF_FormObject()
{
    delete m_pForm;
}
void CPDF_FormObject::Transform(const CFX_AffineMatrix& matrix)
{
    m_FormMatrix.Concat(matrix);
    CalcBoundingBox();
}
void CPDF_FormObject::CopyData(const CPDF_PageObject* pSrc)
{
    const CPDF_FormObject* pSrcObj = (const CPDF_FormObject*)pSrc;
    delete m_pForm;
    m_pForm = pSrcObj->m_pForm->Clone();
    m_FormMatrix = pSrcObj->m_FormMatrix;
}
void CPDF_FormObject::CalcBoundingBox()
{
    CFX_FloatRect form_rect = m_pForm->CalcBoundingBox();
    form_rect.Transform(&m_FormMatrix);
    m_Left = form_rect.left;
    m_Bottom = form_rect.bottom;
    m_Right = form_rect.right;
    m_Top = form_rect.top;
}
CPDF_PageObjects::CPDF_PageObjects(FX_BOOL bReleaseMembers) : m_ObjectList(128)
{
    m_bBackgroundAlphaNeeded = FALSE;
    m_bReleaseMembers = bReleaseMembers;
    m_ParseState = PDF_CONTENT_NOT_PARSED;
    m_pParser = NULL;
    m_pFormStream = NULL;
    m_pResources = NULL;
}
CPDF_PageObjects::~CPDF_PageObjects()
{
    delete m_pParser;
    if (!m_bReleaseMembers) {
        return;
    }
    FX_POSITION pos = m_ObjectList.GetHeadPosition();
    while (pos) {
        delete (CPDF_PageObject*)m_ObjectList.GetNext(pos);
    }
}
void CPDF_PageObjects::ContinueParse(IFX_Pause* pPause)
{
    if (m_pParser == NULL) {
        return;
    }
    m_pParser->Continue(pPause);
    if (m_pParser->GetStatus() == CPDF_ContentParser::Done) {
        m_ParseState = PDF_CONTENT_PARSED;
        delete m_pParser;
        m_pParser = NULL;
    }
}
int CPDF_PageObjects::EstimateParseProgress() const
{
    if (m_pParser == NULL) {
        return m_ParseState == PDF_CONTENT_PARSED ? 100 : 0;
    }
    return m_pParser->EstimateProgress();
}
FX_POSITION CPDF_PageObjects::InsertObject(FX_POSITION posInsertAfter, CPDF_PageObject* pNewObject)
{
    if (posInsertAfter == NULL) {
        return m_ObjectList.AddHead(pNewObject);
    } else {
        return m_ObjectList.InsertAfter(posInsertAfter, pNewObject);
    }
}
int CPDF_PageObjects::GetObjectIndex(CPDF_PageObject* pObj) const
{
    int index = 0;
    FX_POSITION pos = m_ObjectList.GetHeadPosition();
    while (pos) {
        CPDF_PageObject* pThisObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos);
        if (pThisObj == pObj) {
            return index;
        }
        index ++;
    }
    return -1;
}
CPDF_PageObject* CPDF_PageObjects::GetObjectByIndex(int index) const
{
    FX_POSITION pos = m_ObjectList.FindIndex(index);
    if (pos == NULL) {
        return NULL;
    }
    return (CPDF_PageObject*)m_ObjectList.GetAt(pos);
}
void CPDF_PageObjects::Transform(const CFX_AffineMatrix& matrix)
{
    FX_POSITION pos = m_ObjectList.GetHeadPosition();
    while (pos) {
        CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos);
        pObj->Transform(matrix);
    }
}
CFX_FloatRect CPDF_PageObjects::CalcBoundingBox() const
{
    if (m_ObjectList.GetCount() == 0) {
        return CFX_FloatRect(0, 0, 0, 0);
    }
    FX_FLOAT left, right, top, bottom;
    left = bottom = 1000000 * 1.0f;
    right = top = -1000000 * 1.0f;
    FX_POSITION pos = m_ObjectList.GetHeadPosition();
    while (pos) {
        CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos);
        if (left > pObj->m_Left) {
            left = pObj->m_Left;
        }
        if (right < pObj->m_Right) {
            right = pObj->m_Right;
        }
        if (top < pObj->m_Top) {
            top = pObj->m_Top;
        }
        if (bottom > pObj->m_Bottom) {
            bottom = pObj->m_Bottom;
        }
    }
    return CFX_FloatRect(left, bottom, right, top);
}
void CPDF_PageObjects::LoadTransInfo()
{
    if (m_pFormDict == NULL) {
        return;
    }
    CPDF_Dictionary* pGroup = m_pFormDict->GetDict(FX_BSTRC("Group"));
    if (pGroup == NULL) {
        return;
    }
    if (pGroup->GetString(FX_BSTRC("S")) != FX_BSTRC("Transparency")) {
        return;
    }
    m_Transparency |= PDFTRANS_GROUP;
    if (pGroup->GetInteger(FX_BSTRC("I"))) {
        m_Transparency |= PDFTRANS_ISOLATED;
    }
    if (pGroup->GetInteger(FX_BSTRC("K"))) {
        m_Transparency |= PDFTRANS_KNOCKOUT;
    }
}
void CPDF_PageObjects::ClearCacheObjects()
{
    m_ParseState = PDF_CONTENT_NOT_PARSED;
    delete m_pParser;
    m_pParser = NULL;
    if (m_bReleaseMembers) {
        FX_POSITION pos = m_ObjectList.GetHeadPosition();
        while (pos) {
            delete (CPDF_PageObject*)m_ObjectList.GetNext(pos);
        }
    }
    m_ObjectList.RemoveAll();
}
CPDF_Page::CPDF_Page()
{
    m_pPageRender = NULL;
}
void CPDF_Page::Load(CPDF_Document* pDocument, CPDF_Dictionary* pPageDict, FX_BOOL bPageCache)
{
    m_pDocument = (CPDF_Document*)pDocument;
    m_pFormDict = pPageDict;
    if (bPageCache) {
        m_pPageRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreatePageCache(this);
    }
    if (pPageDict == NULL) {
        m_PageWidth = m_PageHeight = 100 * 1.0f;
        m_pPageResources = m_pResources = NULL;
        return;
    }
    CPDF_Object* pageAttr = GetPageAttr(FX_BSTRC("Resources"));
    m_pResources = pageAttr ? pageAttr->GetDict() : NULL;
    m_pPageResources = m_pResources;
    CPDF_Object* pRotate = GetPageAttr(FX_BSTRC("Rotate"));
    int rotate = 0;
    if (pRotate) {
        rotate = pRotate->GetInteger() / 90 % 4;
    }
    if (rotate < 0) {
        rotate += 4;
    }
    CPDF_Array* pMediaBox, *pCropBox;
    pMediaBox = (CPDF_Array*)GetPageAttr(FX_BSTRC("MediaBox"));
    CFX_FloatRect mediabox;
    if (pMediaBox) {
        mediabox = pMediaBox->GetRect();
        mediabox.Normalize();
    }
    if (mediabox.IsEmpty()) {
        mediabox = CFX_FloatRect(0, 0, 612, 792);
    }
    pCropBox = (CPDF_Array*)GetPageAttr(FX_BSTRC("CropBox"));
    if (pCropBox) {
        m_BBox = pCropBox->GetRect();
        m_BBox.Normalize();
    }
    if (m_BBox.IsEmpty()) {
        m_BBox = mediabox;
    } else {
        m_BBox.Intersect(mediabox);
    }
    if (rotate % 2) {
        m_PageHeight = m_BBox.right - m_BBox.left;
        m_PageWidth = m_BBox.top - m_BBox.bottom;
    } else {
        m_PageWidth = m_BBox.right - m_BBox.left;
        m_PageHeight = m_BBox.top - m_BBox.bottom;
    }
    switch (rotate) {
        case 0:
            m_PageMatrix.Set(1.0f, 0, 0, 1.0f, -m_BBox.left, -m_BBox.bottom);
            break;
        case 1:
            m_PageMatrix.Set(0, -1.0f, 1.0f, 0, -m_BBox.bottom, m_BBox.right);
            break;
        case 2:
            m_PageMatrix.Set(-1.0f, 0, 0, -1.0f, m_BBox.right, m_BBox.top);
            break;
        case 3:
            m_PageMatrix.Set(0, 1.0f, -1.0f, 0, m_BBox.top, -m_BBox.left);
            break;
    }
    m_Transparency = PDFTRANS_ISOLATED;
    LoadTransInfo();
}
void CPDF_Page::StartParse(CPDF_ParseOptions* pOptions, FX_BOOL bReParse)
{
    if (bReParse) {
        ClearCacheObjects();
    }
    if (m_ParseState == PDF_CONTENT_PARSED || m_ParseState == PDF_CONTENT_PARSING) {
        return;
    }
    m_pParser = new CPDF_ContentParser;
    m_pParser->Start(this, pOptions);
    m_ParseState = PDF_CONTENT_PARSING;
}
void CPDF_Page::ParseContent(CPDF_ParseOptions* pOptions, FX_BOOL bReParse)
{
    StartParse(pOptions, bReParse);
    ContinueParse(NULL);
}
CPDF_Page::~CPDF_Page()
{
    if (m_pPageRender) {
        IPDF_RenderModule* pModule = CPDF_ModuleMgr::Get()->GetRenderModule();
        pModule->DestroyPageCache(m_pPageRender);
    }
}
CPDF_Object* FPDFAPI_GetPageAttr(CPDF_Dictionary* pPageDict, const CFX_ByteStringC& name)
{
    int level = 0;
    while (1) {
        CPDF_Object* pObj = pPageDict->GetElementValue(name);
        if (pObj) {
            return pObj;
        }
        CPDF_Dictionary* pParent = pPageDict->GetDict(FX_BSTRC("Parent"));
        if (!pParent || pParent == pPageDict) {
            return NULL;
        }
        pPageDict = pParent;
        level ++;
        if (level == 1000) {
            return NULL;
        }
    }
}
CPDF_Object* CPDF_Page::GetPageAttr(const CFX_ByteStringC& name) const
{
    return FPDFAPI_GetPageAttr(m_pFormDict, name);
}
CPDF_Form::CPDF_Form(CPDF_Document* pDoc, CPDF_Dictionary* pPageResources, CPDF_Stream* pFormStream, CPDF_Dictionary* pParentResources)
{
    m_pDocument = pDoc;
    m_pFormStream = pFormStream;
    m_pFormDict = pFormStream ? pFormStream->GetDict() : NULL;
    m_pResources = m_pFormDict->GetDict(FX_BSTRC("Resources"));
    m_pPageResources = pPageResources;
    if (m_pResources == NULL) {
        m_pResources = pParentResources;
    }
    if (m_pResources == NULL) {
        m_pResources = pPageResources;
    }
    m_Transparency = 0;
    LoadTransInfo();
}
CPDF_Form::~CPDF_Form()
{
}
void CPDF_Form::StartParse(CPDF_AllStates* pGraphicStates, CFX_AffineMatrix* pParentMatrix,
                           CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptions, int level)
{
    if (m_ParseState == PDF_CONTENT_PARSED || m_ParseState == PDF_CONTENT_PARSING) {
        return;
    }
    m_pParser = new CPDF_ContentParser;
    m_pParser->Start(this, pGraphicStates, pParentMatrix, pType3Char, pOptions, level);
    m_ParseState = PDF_CONTENT_PARSING;
}
void CPDF_Form::ParseContent(CPDF_AllStates* pGraphicStates, CFX_AffineMatrix* pParentMatrix,
                             CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptions, int level)
{
    StartParse(pGraphicStates, pParentMatrix, pType3Char, pOptions, level);
    ContinueParse(NULL);
}
CPDF_Form* CPDF_Form::Clone() const
{
    CPDF_Form* pClone = new CPDF_Form(m_pDocument, m_pPageResources, m_pFormStream, m_pResources);
    FX_POSITION pos = m_ObjectList.GetHeadPosition();
    while (pos) {
        CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos);
        pClone->m_ObjectList.AddTail(pObj->Clone());
    }
    return pClone;
}
void CPDF_Page::GetDisplayMatrix(CFX_AffineMatrix& matrix, int xPos, int yPos,
                                 int xSize, int ySize, int iRotate) const
{
    if (m_PageWidth == 0 || m_PageHeight == 0) {
        return;
    }
    CFX_AffineMatrix display_matrix;
    int x0, y0, x1, y1, x2, y2;
    iRotate %= 4;
    switch (iRotate) {
        case 0:
            x0 = xPos;
            y0 = yPos + ySize;
            x1 = xPos;
            y1 = yPos;
            x2 = xPos + xSize;
            y2 = yPos + ySize;
            break;
        case 1:
            x0 = xPos;
            y0 = yPos;
            x1 = xPos + xSize;
            y1 = yPos;
            x2 = xPos;
            y2 = yPos + ySize;
            break;
        case 2:
            x0 = xPos + xSize;
            y0 = yPos;
            x1 = xPos + xSize;
            y1 = yPos + ySize;
            x2 = xPos;
            y2 = yPos;
            break;
        case 3:
            x0 = xPos + xSize;
            y0 = yPos + ySize;
            x1 = xPos;
            y1 = yPos + ySize;
            x2 = xPos + xSize;
            y2 = yPos;
            break;
    }
    display_matrix.Set(FXSYS_Div((FX_FLOAT)(x2 - x0), m_PageWidth),
                       FXSYS_Div((FX_FLOAT)(y2 - y0), m_PageWidth),
                       FXSYS_Div((FX_FLOAT)(x1 - x0), m_PageHeight),
                       FXSYS_Div((FX_FLOAT)(y1 - y0), m_PageHeight),
                       (FX_FLOAT)x0, (FX_FLOAT)y0);
    matrix = m_PageMatrix;
    matrix.Concat(display_matrix);
}
CPDF_ParseOptions::CPDF_ParseOptions()
{
    m_bTextOnly = FALSE;
    m_bMarkedContent = TRUE;
    m_bSeparateForm = TRUE;
    m_bDecodeInlineImage = FALSE;
}
