Example #1
0
void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions) {
  if (m_Status != Ready || pPage == NULL || pPage->m_pDocument == NULL ||
      pPage->m_pFormDict == NULL) {
    m_Status = Done;
    return;
  }
  m_pObjects = pPage;
  m_bForm = FALSE;
  if (pOptions) {
    m_Options = *pOptions;
  }
  m_Status = ToBeContinued;
  m_InternalStage = PAGEPARSE_STAGE_GETCONTENT;
  m_CurrentOffset = 0;
  CPDF_Object* pContent =
      pPage->m_pFormDict->GetElementValue(FX_BSTRC("Contents"));
  if (pContent == NULL) {
    m_Status = Done;
    return;
  }
  if (CPDF_Stream* pStream = pContent->AsStream()) {
    m_nStreams = 0;
    m_pSingleStream = new CPDF_StreamAcc;
    m_pSingleStream->LoadAllData(pStream, FALSE);
  } else if (CPDF_Array* pArray = pContent->AsArray()) {
    m_nStreams = pArray->GetCount();
    if (m_nStreams == 0) {
      m_Status = Done;
      return;
    }
    m_pStreamArray = FX_Alloc(CPDF_StreamAcc*, m_nStreams);
  } else {
void CPDF_ContentParser::Start(CPDF_Page* pPage) {
  if (m_Status != Ready || !pPage || !pPage->m_pDocument ||
      !pPage->m_pFormDict) {
    m_Status = Done;
    return;
  }
  m_pObjectHolder = pPage;
  m_bForm = false;
  m_Status = ToBeContinued;
  m_InternalStage = STAGE_GETCONTENT;
  m_CurrentOffset = 0;

  CPDF_Object* pContent = pPage->m_pFormDict->GetDirectObjectFor("Contents");
  if (!pContent) {
    m_Status = Done;
    return;
  }
  if (CPDF_Stream* pStream = pContent->AsStream()) {
    m_nStreams = 0;
    m_pSingleStream.reset(new CPDF_StreamAcc);
    m_pSingleStream->LoadAllData(pStream, false);
  } else if (CPDF_Array* pArray = pContent->AsArray()) {
    m_nStreams = pArray->GetCount();
    if (m_nStreams)
      m_StreamArray.resize(m_nStreams);
    else
      m_Status = Done;
  } else {
    m_Status = Done;
  }
}
Example #3
0
CPDF_Dictionary* CPDF_Array::GetDictAt(size_t i) const {
  CPDF_Object* p = GetDirectObjectAt(i);
  if (!p)
    return nullptr;
  if (CPDF_Dictionary* pDict = p->AsDictionary())
    return pDict;
  if (CPDF_Stream* pStream = p->AsStream())
    return pStream->GetDict();
  return nullptr;
}
CPDF_Dictionary* CPDF_Dictionary::GetDict(const CFX_ByteStringC& key) const {
  CPDF_Object* p = GetElementValue(key);
  if (!p)
    return nullptr;
  if (CPDF_Dictionary* pDict = p->AsDictionary())
    return pDict;
  if (CPDF_Stream* pStream = p->AsStream())
    return pStream->GetDict();
  return nullptr;
}
CPDF_Dictionary* CPDF_Array::GetDict(FX_DWORD i) const {
  CPDF_Object* p = GetElementValue(i);
  if (!p)
    return NULL;
  if (CPDF_Dictionary* pDict = p->AsDictionary())
    return pDict;
  if (CPDF_Stream* pStream = p->AsStream())
    return pStream->GetDict();
  return NULL;
}
Example #6
0
CPDF_Stream* FPDFDOC_GetAnnotAP(CPDF_Dictionary* pAnnotDict,
                                CPDF_Annot::AppearanceMode mode) {
  CPDF_Dictionary* pAP = pAnnotDict->GetDictBy("AP");
  if (!pAP) {
    return nullptr;
  }
  const FX_CHAR* ap_entry = "N";
  if (mode == CPDF_Annot::Down)
    ap_entry = "D";
  else if (mode == CPDF_Annot::Rollover)
    ap_entry = "R";
  if (!pAP->KeyExist(ap_entry))
    ap_entry = "N";

  CPDF_Object* psub = pAP->GetDirectObjectBy(ap_entry);
  if (!psub)
    return nullptr;
  if (CPDF_Stream* pStream = psub->AsStream())
    return pStream;

  if (CPDF_Dictionary* pDict = psub->AsDictionary()) {
    CFX_ByteString as = pAnnotDict->GetStringBy("AS");
    if (as.IsEmpty()) {
      CFX_ByteString value = pAnnotDict->GetStringBy("V");
      if (value.IsEmpty()) {
        CPDF_Dictionary* pParentDict = pAnnotDict->GetDictBy("Parent");
        value = pParentDict ? pParentDict->GetStringBy("V") : CFX_ByteString();
      }
      if (value.IsEmpty() || !pDict->KeyExist(value))
        as = "Off";
      else
        as = value;
    }
    return pDict->GetStreamBy(as);
  }
  return nullptr;
}
FX_BOOL CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
  if (pArray->GetCount() < 4) {
    return FALSE;
  }
  CPDF_Object* pBaseObj = pArray->GetElementValue(1);
  if (pBaseObj == m_pArray) {
    return FALSE;
  }
  CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
  m_pBaseCS = pDocPageData->GetColorSpace(pBaseObj, NULL);
  if (!m_pBaseCS) {
    return FALSE;
  }
  m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray());
  m_nBaseComponents = m_pBaseCS->CountComponents();
  m_pCompMinMax = FX_Alloc2D(FX_FLOAT, m_nBaseComponents, 2);
  FX_FLOAT defvalue;
  for (int i = 0; i < m_nBaseComponents; i++) {
    m_pBaseCS->GetDefaultValue(i, defvalue, m_pCompMinMax[i * 2],
                               m_pCompMinMax[i * 2 + 1]);
    m_pCompMinMax[i * 2 + 1] -= m_pCompMinMax[i * 2];
  }
  m_MaxIndex = pArray->GetInteger(2);

  CPDF_Object* pTableObj = pArray->GetElementValue(3);
  if (!pTableObj)
    return FALSE;

  if (CPDF_String* pString = pTableObj->AsString()) {
    m_Table = pString->GetString();
  } else if (CPDF_Stream* pStream = pTableObj->AsStream()) {
    CPDF_StreamAcc acc;
    acc.LoadAllData(pStream, FALSE);
    m_Table = CFX_ByteStringC(acc.GetData(), acc.GetSize());
  }
  return TRUE;
}
Example #8
0
CPDF_ContentParser::CPDF_ContentParser(CPDF_Page* pPage)
    : m_CurrentStage(Stage::kGetContent), m_pObjectHolder(pPage) {
  ASSERT(pPage);
  if (!pPage->GetDocument() || !pPage->GetDict()) {
    m_CurrentStage = Stage::kComplete;
    return;
  }

  CPDF_Object* pContent =
      pPage->GetDict()->GetDirectObjectFor(pdfium::page_object::kContents);
  if (!pContent) {
    m_CurrentStage = Stage::kComplete;
    return;
  }

  CPDF_Stream* pStream = pContent->AsStream();
  if (pStream) {
    m_pSingleStream = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
    m_pSingleStream->LoadAllDataFiltered();
    m_CurrentStage = Stage::kPrepareContent;
    return;
  }

  CPDF_Array* pArray = pContent->AsArray();
  if (!pArray) {
    m_CurrentStage = Stage::kComplete;
    return;
  }

  m_nStreams = pArray->size();
  if (m_nStreams == 0) {
    m_CurrentStage = Stage::kComplete;
    return;
  }
  m_StreamArray.resize(m_nStreams);
}
Example #9
0
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDFPage_TransFormWithClip(FPDF_PAGE page,
                           const FS_MATRIX* matrix,
                           const FS_RECTF* clipRect) {
  if (!matrix && !clipRect)
    return false;

  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
  if (!pPage)
    return false;

  std::ostringstream textBuf;
  textBuf << "q ";

  if (clipRect) {
    CFX_FloatRect rect = CFXFloatRectFromFSRECTF(*clipRect);
    rect.Normalize();

    textBuf << ByteString::Format("%f %f %f %f re W* n ", rect.left,
                                  rect.bottom, rect.Width(), rect.Height());
  }
  if (matrix) {
    textBuf << ByteString::Format("%f %f %f %f %f %f cm ", matrix->a, matrix->b,
                                  matrix->c, matrix->d, matrix->e, matrix->f);
  }

  CPDF_Dictionary* pPageDict = pPage->GetDict();
  CPDF_Object* pContentObj = GetPageContent(pPageDict);
  if (!pContentObj)
    return false;

  CPDF_Document* pDoc = pPage->GetDocument();
  if (!pDoc)
    return false;

  CPDF_Stream* pStream =
      pDoc->NewIndirect<CPDF_Stream>(nullptr, 0, pDoc->New<CPDF_Dictionary>());
  pStream->SetDataFromStringstream(&textBuf);

  CPDF_Stream* pEndStream =
      pDoc->NewIndirect<CPDF_Stream>(nullptr, 0, pDoc->New<CPDF_Dictionary>());
  pEndStream->SetData(ByteStringView(" Q").span());

  if (CPDF_Array* pContentArray = ToArray(pContentObj)) {
    pContentArray->InsertAt(0, pStream->MakeReference(pDoc));
    pContentArray->Add(pEndStream->MakeReference(pDoc));
  } else if (pContentObj->IsStream() && !pContentObj->IsInline()) {
    pContentArray = pDoc->NewIndirect<CPDF_Array>();
    pContentArray->Add(pStream->MakeReference(pDoc));
    pContentArray->Add(pContentObj->MakeReference(pDoc));
    pContentArray->Add(pEndStream->MakeReference(pDoc));
    pPageDict->SetFor(pdfium::page_object::kContents,
                      pContentArray->MakeReference(pDoc));
  }

  // Need to transform the patterns as well.
  CPDF_Dictionary* pRes =
      pPageDict->GetDictFor(pdfium::page_object::kResources);
  if (!pRes)
    return true;

  CPDF_Dictionary* pPatternDict = pRes->GetDictFor("Pattern");
  if (!pPatternDict)
    return true;

  CPDF_DictionaryLocker locker(pPatternDict);
  for (const auto& it : locker) {
    CPDF_Object* pObj = it.second.get();
    if (pObj->IsReference())
      pObj = pObj->GetDirect();

    CPDF_Dictionary* pDict = nullptr;
    if (pObj->IsDictionary())
      pDict = pObj->AsDictionary();
    else if (CPDF_Stream* pObjStream = pObj->AsStream())
      pDict = pObjStream->GetDict();
    else
      continue;

    if (matrix) {
      CFX_Matrix m = CFXMatrixFromFSMatrix(*matrix);
      pDict->SetMatrixFor("Matrix", pDict->GetMatrixFor("Matrix") * m);
    }
  }

  return true;
}
Example #10
0
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_TransFormWithClip(FPDF_PAGE page,
                                                       FS_MATRIX* matrix,
                                                       FS_RECTF* clipRect) {
  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
  if (!pPage)
    return FALSE;

  CFX_ByteTextBuf textBuf;
  textBuf << "q ";
  CFX_FloatRect rect(clipRect->left, clipRect->bottom, clipRect->right,
                     clipRect->top);
  rect.Normalize();
  CFX_ByteString bsClipping;
  bsClipping.Format("%f %f %f %f re W* n ", rect.left, rect.bottom,
                    rect.Width(), rect.Height());
  textBuf << bsClipping;

  CFX_ByteString bsMatix;
  bsMatix.Format("%f %f %f %f %f %f cm ", matrix->a, matrix->b, matrix->c,
                 matrix->d, matrix->e, matrix->f);
  textBuf << bsMatix;

  CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
  CPDF_Object* pContentObj =
      pPageDic ? pPageDic->GetElement("Contents") : nullptr;
  if (!pContentObj)
    pContentObj = pPageDic ? pPageDic->GetArrayBy("Contents") : nullptr;
  if (!pContentObj)
    return FALSE;

  CPDF_Dictionary* pDic = new CPDF_Dictionary;
  CPDF_Stream* pStream = new CPDF_Stream(nullptr, 0, pDic);
  pStream->SetData(textBuf.GetBuffer(), textBuf.GetSize(), FALSE, FALSE);
  CPDF_Document* pDoc = pPage->m_pDocument;
  if (!pDoc)
    return FALSE;
  pDoc->AddIndirectObject(pStream);

  pDic = new CPDF_Dictionary;
  CPDF_Stream* pEndStream = new CPDF_Stream(nullptr, 0, pDic);
  pEndStream->SetData((const uint8_t*)" Q", 2, FALSE, FALSE);
  pDoc->AddIndirectObject(pEndStream);

  CPDF_Array* pContentArray = nullptr;
  if (CPDF_Array* pArray = ToArray(pContentObj)) {
    pContentArray = pArray;
    CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
    pContentArray->InsertAt(0, pRef);
    pContentArray->AddReference(pDoc, pEndStream);
  } else if (CPDF_Reference* pReference = ToReference(pContentObj)) {
    CPDF_Object* pDirectObj = pReference->GetDirect();
    if (pDirectObj) {
      if (CPDF_Array* pArray = pDirectObj->AsArray()) {
        pContentArray = pArray;
        CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
        pContentArray->InsertAt(0, pRef);
        pContentArray->AddReference(pDoc, pEndStream);
      } else if (pDirectObj->IsStream()) {
        pContentArray = new CPDF_Array();
        pContentArray->AddReference(pDoc, pStream->GetObjNum());
        pContentArray->AddReference(pDoc, pDirectObj->GetObjNum());
        pContentArray->AddReference(pDoc, pEndStream);
        pPageDic->SetAtReference("Contents", pDoc,
                                 pDoc->AddIndirectObject(pContentArray));
      }
    }
  }

  // Need to transform the patterns as well.
  CPDF_Dictionary* pRes = pPageDic->GetDictBy("Resources");
  if (pRes) {
    CPDF_Dictionary* pPattenDict = pRes->GetDictBy("Pattern");
    if (pPattenDict) {
      for (const auto& it : *pPattenDict) {
        CPDF_Object* pObj = it.second;
        if (pObj->IsReference())
          pObj = pObj->GetDirect();

        CPDF_Dictionary* pDict = nullptr;
        if (pObj->IsDictionary())
          pDict = pObj->AsDictionary();
        else if (CPDF_Stream* pStream = pObj->AsStream())
          pDict = pStream->GetDict();
        else
          continue;

        CFX_Matrix m = pDict->GetMatrixBy("Matrix");
        CFX_Matrix t = *(CFX_Matrix*)matrix;
        m.Concat(t);
        pDict->SetAtMatrix("Matrix", m);
      }
    }
  }

  return TRUE;
}
Example #11
0
bool CPDF_CIDFont::Load() {
  if (m_pFontDict->GetStringFor("Subtype") == "TrueType") {
    LoadGB2312();
    return true;
  }

  CPDF_Array* pFonts = m_pFontDict->GetArrayFor("DescendantFonts");
  if (!pFonts || pFonts->GetCount() != 1)
    return false;

  CPDF_Dictionary* pCIDFontDict = pFonts->GetDictAt(0);
  if (!pCIDFontDict)
    return false;

  m_BaseFont = pCIDFontDict->GetStringFor("BaseFont");
  if ((m_BaseFont.Compare("CourierStd") == 0 ||
       m_BaseFont.Compare("CourierStd-Bold") == 0 ||
       m_BaseFont.Compare("CourierStd-BoldOblique") == 0 ||
       m_BaseFont.Compare("CourierStd-Oblique") == 0) &&
      !IsEmbedded()) {
    m_bAdobeCourierStd = true;
  }
  CPDF_Dictionary* pFontDesc = pCIDFontDict->GetDictFor("FontDescriptor");
  if (pFontDesc)
    LoadFontDescriptor(pFontDesc);

  CPDF_Object* pEncoding = m_pFontDict->GetDirectObjectFor("Encoding");
  if (!pEncoding)
    return false;

  CFX_ByteString subtype = pCIDFontDict->GetStringFor("Subtype");
  m_bType1 = (subtype == "CIDFontType0");

  CPDF_CMapManager& manager = GetFontGlobals()->m_CMapManager;
  if (pEncoding->IsName()) {
    CFX_ByteString cmap = pEncoding->GetString();
    bool bPromptCJK = m_pFontFile && m_bType1;
    m_pCMap = manager.GetPredefinedCMap(cmap, bPromptCJK);
    if (!m_pCMap)
      return false;
  } else if (CPDF_Stream* pStream = pEncoding->AsStream()) {
    m_pCMap = pdfium::MakeUnique<CPDF_CMap>();
    CPDF_StreamAcc acc;
    acc.LoadAllData(pStream, false);
    m_pCMap->LoadEmbedded(acc.GetData(), acc.GetSize());
  } else {
    return false;
  }

  m_Charset = m_pCMap->m_Charset;
  if (m_Charset == CIDSET_UNKNOWN) {
    CPDF_Dictionary* pCIDInfo = pCIDFontDict->GetDictFor("CIDSystemInfo");
    if (pCIDInfo) {
      m_Charset =
          CharsetFromOrdering(pCIDInfo->GetStringFor("Ordering").AsStringC());
    }
  }
  if (m_Charset != CIDSET_UNKNOWN) {
    bool bPromptCJK = !m_pFontFile && (m_pCMap->m_Coding == CIDCODING_CID ||
                                       pCIDFontDict->KeyExist("W"));
    m_pCID2UnicodeMap = manager.GetCID2UnicodeMap(m_Charset, bPromptCJK);
  }
  if (m_Font.GetFace()) {
    if (m_bType1)
      FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE);
    else
      FT_UseCIDCharmap(m_Font.GetFace(), m_pCMap->m_Coding);
  }
  m_DefaultWidth = pCIDFontDict->GetIntegerFor("DW", 1000);
  CPDF_Array* pWidthArray = pCIDFontDict->GetArrayFor("W");
  if (pWidthArray)
    LoadMetricsArray(pWidthArray, &m_WidthList, 1);
  if (!IsEmbedded())
    LoadSubstFont();

  if (m_pFontFile || (GetSubstFont()->m_SubstFlags & FXFONT_SUBST_EXACT)) {
    CPDF_Object* pmap = pCIDFontDict->GetDirectObjectFor("CIDToGIDMap");
    if (pmap) {
      if (CPDF_Stream* pStream = pmap->AsStream()) {
        m_pStreamAcc = pdfium::MakeUnique<CPDF_StreamAcc>();
        m_pStreamAcc->LoadAllData(pStream, false);
      } else if (pmap->GetString() == "Identity") {
#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
        if (m_pFontFile)
          m_bCIDIsGID = true;
#else
        m_bCIDIsGID = true;
#endif
      }
    }
  }

  CheckFontMetrics();
  if (IsVertWriting()) {
    pWidthArray = pCIDFontDict->GetArrayFor("W2");
    if (pWidthArray)
      LoadMetricsArray(pWidthArray, &m_VertMetrics, 3);
    CPDF_Array* pDefaultArray = pCIDFontDict->GetArrayFor("DW2");
    if (pDefaultArray) {
      m_DefaultVY = pDefaultArray->GetIntegerAt(0);
      m_DefaultW1 = pDefaultArray->GetIntegerAt(1);
    } else {
      m_DefaultVY = 880;
      m_DefaultW1 = -1000;
    }
  }
  return true;
}
Example #12
0
DLLEXPORT int STDCALL FPDFPage_Flatten(FPDF_PAGE page, int nFlag) {
  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
  if (!page) {
    return FLATTEN_FAIL;
  }

  CPDF_Document* pDocument = pPage->m_pDocument;
  CPDF_Dictionary* pPageDict = pPage->m_pFormDict;

  if (!pDocument || !pPageDict) {
    return FLATTEN_FAIL;
  }

  CPDF_ObjectArray ObjectArray;
  CPDF_RectArray RectArray;

  int iRet = FLATTEN_FAIL;
  iRet = ParserAnnots(pDocument, pPageDict, &RectArray, &ObjectArray, nFlag);
  if (iRet == FLATTEN_NOTHINGTODO || iRet == FLATTEN_FAIL)
    return iRet;

  CFX_FloatRect rcOriginalCB;
  CFX_FloatRect rcMerger = CalculateRect(&RectArray);
  CFX_FloatRect rcOriginalMB = pPageDict->GetRectFor("MediaBox");

  if (pPageDict->KeyExist("CropBox"))
    rcOriginalMB = pPageDict->GetRectFor("CropBox");

  if (rcOriginalMB.IsEmpty()) {
    rcOriginalMB = CFX_FloatRect(0.0f, 0.0f, 612.0f, 792.0f);
  }

  rcMerger.left =
      rcMerger.left < rcOriginalMB.left ? rcOriginalMB.left : rcMerger.left;
  rcMerger.right =
      rcMerger.right > rcOriginalMB.right ? rcOriginalMB.right : rcMerger.right;
  rcMerger.top =
      rcMerger.top > rcOriginalMB.top ? rcOriginalMB.top : rcMerger.top;
  rcMerger.bottom = rcMerger.bottom < rcOriginalMB.bottom ? rcOriginalMB.bottom
                                                          : rcMerger.bottom;

  if (pPageDict->KeyExist("ArtBox"))
    rcOriginalCB = pPageDict->GetRectFor("ArtBox");
  else
    rcOriginalCB = rcOriginalMB;

  if (!rcOriginalMB.IsEmpty()) {
    CPDF_Array* pMediaBox = new CPDF_Array();
    pMediaBox->Add(new CPDF_Number(rcOriginalMB.left));
    pMediaBox->Add(new CPDF_Number(rcOriginalMB.bottom));
    pMediaBox->Add(new CPDF_Number(rcOriginalMB.right));
    pMediaBox->Add(new CPDF_Number(rcOriginalMB.top));
    pPageDict->SetFor("MediaBox", pMediaBox);
  }

  if (!rcOriginalCB.IsEmpty()) {
    CPDF_Array* pCropBox = new CPDF_Array();
    pCropBox->Add(new CPDF_Number(rcOriginalCB.left));
    pCropBox->Add(new CPDF_Number(rcOriginalCB.bottom));
    pCropBox->Add(new CPDF_Number(rcOriginalCB.right));
    pCropBox->Add(new CPDF_Number(rcOriginalCB.top));
    pPageDict->SetFor("ArtBox", pCropBox);
  }

  CPDF_Dictionary* pRes = pPageDict->GetDictFor("Resources");
  if (!pRes) {
    pRes = new CPDF_Dictionary(pDocument->GetByteStringPool());
    pPageDict->SetFor("Resources", pRes);
  }

  CPDF_Stream* pNewXObject = new CPDF_Stream(
      nullptr, 0, new CPDF_Dictionary(pDocument->GetByteStringPool()));

  uint32_t dwObjNum = pDocument->AddIndirectObject(pNewXObject);
  CPDF_Dictionary* pPageXObject = pRes->GetDictFor("XObject");
  if (!pPageXObject) {
    pPageXObject = new CPDF_Dictionary(pDocument->GetByteStringPool());
    pRes->SetFor("XObject", pPageXObject);
  }

  CFX_ByteString key = "";
  int nStreams = ObjectArray.GetSize();

  if (nStreams > 0) {
    for (int iKey = 0; /*iKey < 100*/; iKey++) {
      char sExtend[5] = {};
      FXSYS_itoa(iKey, sExtend, 10);
      key = CFX_ByteString("FFT") + CFX_ByteString(sExtend);
      if (!pPageXObject->KeyExist(key))
        break;
    }
  }

  SetPageContents(key, pPageDict, pDocument);

  CPDF_Dictionary* pNewXORes = nullptr;

  if (!key.IsEmpty()) {
    pPageXObject->SetReferenceFor(key, pDocument, dwObjNum);
    CPDF_Dictionary* pNewOXbjectDic = pNewXObject->GetDict();
    pNewXORes = new CPDF_Dictionary(pDocument->GetByteStringPool());
    pNewOXbjectDic->SetFor("Resources", pNewXORes);
    pNewOXbjectDic->SetNameFor("Type", "XObject");
    pNewOXbjectDic->SetNameFor("Subtype", "Form");
    pNewOXbjectDic->SetIntegerFor("FormType", 1);
    pNewOXbjectDic->SetNameFor("Name", "FRM");
    CFX_FloatRect rcBBox = pPageDict->GetRectFor("ArtBox");
    pNewOXbjectDic->SetRectFor("BBox", rcBBox);
  }

  for (int i = 0; i < nStreams; i++) {
    CPDF_Dictionary* pAnnotDic = ObjectArray.GetAt(i);
    if (!pAnnotDic)
      continue;

    CFX_FloatRect rcAnnot = pAnnotDic->GetRectFor("Rect");
    rcAnnot.Normalize();

    CFX_ByteString sAnnotState = pAnnotDic->GetStringFor("AS");
    CPDF_Dictionary* pAnnotAP = pAnnotDic->GetDictFor("AP");
    if (!pAnnotAP)
      continue;

    CPDF_Stream* pAPStream = pAnnotAP->GetStreamFor("N");
    if (!pAPStream) {
      CPDF_Dictionary* pAPDic = pAnnotAP->GetDictFor("N");
      if (!pAPDic)
        continue;

      if (!sAnnotState.IsEmpty()) {
        pAPStream = pAPDic->GetStreamFor(sAnnotState);
      } else {
        auto it = pAPDic->begin();
        if (it != pAPDic->end()) {
          CPDF_Object* pFirstObj = it->second;
          if (pFirstObj) {
            if (pFirstObj->IsReference())
              pFirstObj = pFirstObj->GetDirect();
            if (!pFirstObj->IsStream())
              continue;
            pAPStream = pFirstObj->AsStream();
          }
        }
      }
    }
    if (!pAPStream)
      continue;

    CPDF_Dictionary* pAPDic = pAPStream->GetDict();
    CFX_Matrix matrix = pAPDic->GetMatrixFor("Matrix");

    CFX_FloatRect rcStream;
    if (pAPDic->KeyExist("Rect"))
      rcStream = pAPDic->GetRectFor("Rect");
    else if (pAPDic->KeyExist("BBox"))
      rcStream = pAPDic->GetRectFor("BBox");

    if (rcStream.IsEmpty())
      continue;

    CPDF_Object* pObj = pAPStream;

    if (pObj) {
      CPDF_Dictionary* pObjDic = pObj->GetDict();
      if (pObjDic) {
        pObjDic->SetNameFor("Type", "XObject");
        pObjDic->SetNameFor("Subtype", "Form");
      }
    }

    CPDF_Dictionary* pXObject = pNewXORes->GetDictFor("XObject");
    if (!pXObject) {
      pXObject = new CPDF_Dictionary(pDocument->GetByteStringPool());
      pNewXORes->SetFor("XObject", pXObject);
    }

    CFX_ByteString sFormName;
    sFormName.Format("F%d", i);
    pXObject->SetReferenceFor(sFormName, pDocument,
                              pDocument->AddIndirectObject(pObj));

    CPDF_StreamAcc acc;
    acc.LoadAllData(pNewXObject);

    const uint8_t* pData = acc.GetData();
    CFX_ByteString sStream(pData, acc.GetSize());

    if (matrix.IsIdentity()) {
      matrix.a = 1.0f;
      matrix.b = 0.0f;
      matrix.c = 0.0f;
      matrix.d = 1.0f;
      matrix.e = 0.0f;
      matrix.f = 0.0f;
    }

    CFX_ByteString sTemp;
    CFX_Matrix m = GetMatrix(rcAnnot, rcStream, matrix);
    sTemp.Format("q %f 0 0 %f %f %f cm /%s Do Q\n", m.a, m.d, m.e, m.f,
                 sFormName.c_str());
    sStream += sTemp;
    pNewXObject->SetData(sStream.raw_str(), sStream.GetLength());
  }
  pPageDict->RemoveFor("Annots");

  ObjectArray.RemoveAll();
  RectArray.RemoveAll();

  return FLATTEN_SUCCESS;
}
Example #13
0
void SetPageContents(CFX_ByteString key,
                     CPDF_Dictionary* pPage,
                     CPDF_Document* pDocument) {
  CPDF_Object* pContentsObj = pPage->GetStreamFor("Contents");
  if (!pContentsObj) {
    pContentsObj = pPage->GetArrayFor("Contents");
  }

  if (!pContentsObj) {
    // Create a new contents dictionary
    if (!key.IsEmpty()) {
      CPDF_Stream* pNewContents = new CPDF_Stream(
          nullptr, 0, new CPDF_Dictionary(pDocument->GetByteStringPool()));
      CFX_ByteString sStream;
      sStream.Format("q 1 0 0 1 0 0 cm /%s Do Q", key.c_str());
      pNewContents->SetData(sStream.raw_str(), sStream.GetLength());
      pPage->SetReferenceFor("Contents", pDocument,
                             pDocument->AddIndirectObject(pNewContents));
    }
    return;
  }

  CPDF_Array* pContentsArray = nullptr;
  switch (pContentsObj->GetType()) {
    case CPDF_Object::STREAM: {
      pContentsArray = new CPDF_Array;
      CPDF_Stream* pContents = pContentsObj->AsStream();
      uint32_t dwObjNum = pDocument->AddIndirectObject(pContents);
      CPDF_StreamAcc acc;
      acc.LoadAllData(pContents);
      CFX_ByteString sStream = "q\n";
      CFX_ByteString sBody =
          CFX_ByteString((const FX_CHAR*)acc.GetData(), acc.GetSize());
      sStream = sStream + sBody + "\nQ";
      pContents->SetData(sStream.raw_str(), sStream.GetLength());
      pContentsArray->AddReference(pDocument, dwObjNum);
      break;
    }

    case CPDF_Object::ARRAY: {
      pContentsArray = pContentsObj->AsArray();
      break;
    }
    default:
      break;
  }

  if (!pContentsArray)
    return;

  pPage->SetReferenceFor("Contents", pDocument,
                         pDocument->AddIndirectObject(pContentsArray));

  if (!key.IsEmpty()) {
    CPDF_Stream* pNewContents = new CPDF_Stream(
        nullptr, 0, new CPDF_Dictionary(pDocument->GetByteStringPool()));
    CFX_ByteString sStream;
    sStream.Format("q 1 0 0 1 0 0 cm /%s Do Q", key.c_str());
    pNewContents->SetData(sStream.raw_str(), sStream.GetLength());
    pContentsArray->AddReference(pDocument,
                                 pDocument->AddIndirectObject(pNewContents));
  }
}
Example #14
0
bool CPDF_CIDFont::Load() {
  if (m_pFontDict->GetStringFor("Subtype") == "TrueType") {
    LoadGB2312();
    return true;
  }

  const CPDF_Array* pFonts = m_pFontDict->GetArrayFor("DescendantFonts");
  if (!pFonts || pFonts->size() != 1)
    return false;

  const CPDF_Dictionary* pCIDFontDict = pFonts->GetDictAt(0);
  if (!pCIDFontDict)
    return false;

  m_BaseFont = pCIDFontDict->GetStringFor("BaseFont");
  if ((m_BaseFont.Compare("CourierStd") == 0 ||
       m_BaseFont.Compare("CourierStd-Bold") == 0 ||
       m_BaseFont.Compare("CourierStd-BoldOblique") == 0 ||
       m_BaseFont.Compare("CourierStd-Oblique") == 0) &&
      !IsEmbedded()) {
    m_bAdobeCourierStd = true;
  }
  const CPDF_Dictionary* pFontDesc = pCIDFontDict->GetDictFor("FontDescriptor");
  if (pFontDesc)
    LoadFontDescriptor(pFontDesc);

  CPDF_Object* pEncoding = m_pFontDict->GetDirectObjectFor("Encoding");
  if (!pEncoding)
    return false;

  ByteString subtype = pCIDFontDict->GetStringFor("Subtype");
  m_bType1 = (subtype == "CIDFontType0");

  CPDF_CMapManager* manager = GetFontGlobals()->GetCMapManager();
  if (pEncoding->IsName()) {
    ByteString cmap = pEncoding->GetString();
    m_pCMap = manager->GetPredefinedCMap(cmap);
    if (!m_pCMap)
      return false;
  } else if (CPDF_Stream* pStream = pEncoding->AsStream()) {
    auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
    pAcc->LoadAllDataFiltered();
    m_pCMap = pdfium::MakeRetain<CPDF_CMap>();
    m_pCMap->LoadEmbedded(pAcc->GetSpan());
  } else {
    return false;
  }

  m_Charset = m_pCMap->GetCharset();
  if (m_Charset == CIDSET_UNKNOWN) {
    const CPDF_Dictionary* pCIDInfo = pCIDFontDict->GetDictFor("CIDSystemInfo");
    if (pCIDInfo) {
      m_Charset = CPDF_CMapParser::CharsetFromOrdering(
          pCIDInfo->GetStringFor("Ordering").AsStringView());
    }
  }
  if (m_Charset != CIDSET_UNKNOWN) {
    m_pCID2UnicodeMap = manager->GetCID2UnicodeMap(m_Charset);
  }
  if (m_Font.GetFace()) {
    if (m_bType1)
      FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE);
    else
      FT_UseCIDCharmap(m_Font.GetFace(), m_pCMap->GetCoding());
  }
  m_DefaultWidth = pCIDFontDict->GetIntegerFor("DW", 1000);
  const CPDF_Array* pWidthArray = pCIDFontDict->GetArrayFor("W");
  if (pWidthArray)
    LoadMetricsArray(pWidthArray, &m_WidthList, 1);
  if (!IsEmbedded())
    LoadSubstFont();

  const CPDF_Object* pmap = pCIDFontDict->GetDirectObjectFor("CIDToGIDMap");
  if (pmap) {
    if (const CPDF_Stream* pStream = pmap->AsStream()) {
      m_pStreamAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
      m_pStreamAcc->LoadAllDataFiltered();
    } else if (m_pFontFile && pmap->GetString() == "Identity") {
      m_bCIDIsGID = true;
    }
  }

  CheckFontMetrics();
  if (IsVertWriting()) {
    pWidthArray = pCIDFontDict->GetArrayFor("W2");
    if (pWidthArray)
      LoadMetricsArray(pWidthArray, &m_VertMetrics, 3);
    const CPDF_Array* pDefaultArray = pCIDFontDict->GetArrayFor("DW2");
    if (pDefaultArray) {
      m_DefaultVY = pDefaultArray->GetIntegerAt(0);
      m_DefaultW1 = pDefaultArray->GetIntegerAt(1);
    }
  }
  return true;
}