예제 #1
0
FX_BOOL CPDFSDK_WidgetHandler::CanAnswer(CPDFSDK_Annot* pAnnot) {
  ASSERT(pAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::WIDGET);
  if (pAnnot->IsSignatureWidget())
    return FALSE;

  CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot);
  if (!pWidget->IsVisible())
    return FALSE;

  int nFieldFlags = pWidget->GetFieldFlags();
  if ((nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY)
    return FALSE;

  if (pWidget->GetFieldType() == FIELDTYPE_PUSHBUTTON)
    return TRUE;

  CPDF_Page* pPage = pWidget->GetPDFPage();
  CPDF_Document* pDocument = pPage->m_pDocument;
  uint32_t dwPermissions = pDocument->GetUserPermissions();
  return (dwPermissions & FPDFPERM_FILL_FORM) ||
         (dwPermissions & FPDFPERM_ANNOT_FORM);
}
예제 #2
0
CPDF_Font* CBA_FontMap::FindResFontSameCharset(CPDF_Dictionary* pResDict, CFX_ByteString& sFontAlias, 
													FX_INT32 nCharset)
{
	if (!pResDict) return NULL;

	CPDF_Document* pDocument = GetDocument();
	ASSERT(pDocument != NULL);

	CPDF_Dictionary* pFonts = pResDict->GetDict("Font");
	if (pFonts == NULL) return NULL;

	CPDF_Font* pFind = NULL;

	FX_POSITION pos = pFonts->GetStartPos();
	while (pos)
	{
		CPDF_Object* pObj = NULL;
		CFX_ByteString csKey;
		pObj = pFonts->GetNextElement(pos, csKey);
		if (pObj == NULL) continue;

		CPDF_Object* pDirect = pObj->GetDirect();
		if (pDirect == NULL || pDirect->GetType() != PDFOBJ_DICTIONARY) continue;

		CPDF_Dictionary* pElement = (CPDF_Dictionary*)pDirect;
		if (pElement->GetString("Type") != "Font") continue;

		CPDF_Font* pFont = pDocument->LoadFont(pElement);
		if (pFont == NULL) continue;
		const CFX_SubstFont* pSubst = pFont->GetSubstFont();
		if (pSubst == NULL) continue;
		if (pSubst->m_Charset == nCharset)
		{
			sFontAlias = csKey;
			pFind = pFont;
		}
	}
	return pFind;
}
예제 #3
0
DLLEXPORT FPDF_BOOL STDCALL FPDF_CopyViewerPreferences(FPDF_DOCUMENT dest_doc,
                                                       FPDF_DOCUMENT src_doc) {
  CPDF_Document* pDstDoc = CPDFDocumentFromFPDFDocument(dest_doc);
  if (!pDstDoc)
    return FALSE;

  CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc);
  if (!pSrcDoc)
    return FALSE;

  CPDF_Dictionary* pSrcDict = pSrcDoc->GetRoot();
  pSrcDict = pSrcDict->GetDict(FX_BSTRC("ViewerPreferences"));
  if (!pSrcDict)
    return FALSE;

  CPDF_Dictionary* pDstDict = pDstDoc->GetRoot();
  if (!pDstDict)
    return FALSE;

  pDstDict->SetAt(FX_BSTRC("ViewerPreferences"), pSrcDict->Clone(TRUE));
  return TRUE;
}
DLLEXPORT unsigned long STDCALL FPDF_GetMetaText(FPDF_DOCUMENT doc, FPDF_BYTESTRING tag,
												 void* buffer, unsigned long buflen)
{
	if (doc == NULL || tag == NULL) return 0;

	CPDF_Document* pDoc = (CPDF_Document*)doc;
	// Get info dictionary
	CPDF_Dictionary* pInfo = pDoc->GetInfo();
	if (pInfo == NULL) return 0;

	CFX_WideString text = pInfo->GetUnicodeText(tag);

	// Use UTF-16LE encoding
	CFX_ByteString bstr = text.UTF16LE_Encode();
	unsigned long len = bstr.GetLength();
	if (buffer != NULL || buflen >= len+2) {
		FXSYS_memcpy(buffer, (FX_LPCSTR)bstr, len);
		// use double zero as trailer
		((FX_BYTE*)buffer)[len] = ((FX_BYTE*)buffer)[len+1] = 0;
	}
	return len+2;
}
예제 #5
0
FX_BOOL CPDFSDK_BFAnnotHandler::CanAnswer(CPDFSDK_Annot* pAnnot) {
  ASSERT(pAnnot->GetType() == "Widget");
  if (pAnnot->GetSubType() == BFFT_SIGNATURE)
    return FALSE;

  CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
  if (!pWidget->IsVisible())
    return FALSE;

  int nFieldFlags = pWidget->GetFieldFlags();
  if ((nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY)
    return FALSE;

  if (pWidget->GetFieldType() == FIELDTYPE_PUSHBUTTON)
    return TRUE;

  CPDF_Page* pPage = pWidget->GetPDFPage();
  CPDF_Document* pDocument = pPage->m_pDocument;
  FX_DWORD dwPermissions = pDocument->GetUserPermissions();
  return (dwPermissions & FPDFPERM_FILL_FORM) ||
         (dwPermissions & FPDFPERM_ANNOT_FORM);
}
예제 #6
0
DLLEXPORT void STDCALL FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle, int aaType)
{
	if(!hHandle)
		return;
	CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
	if(pSDKDoc)
	{
		CPDF_Document* pDoc = pSDKDoc->GetDocument();
		CPDF_Dictionary* pDic = pDoc->GetRoot();
		if (!pDic)
			return;
		CPDF_AAction aa = pDic->GetDict(FX_BSTRC("AA"));
		
		if(aa.ActionExist((CPDF_AAction::AActionType)aaType))
		{
			CPDF_Action action = aa.GetAction((CPDF_AAction::AActionType)aaType);
			CPDFSDK_ActionHandler *pActionHandler = ((CPDFDoc_Environment*)hHandle)->GetActionHander();
			ASSERT(pActionHandler != NULL);
			pActionHandler->DoAction_Document(action, (CPDF_AAction::AActionType)aaType, pSDKDoc);
		}
	}
}
예제 #7
0
CPDF_Font* CBA_FontMap::FindFontSameCharset(CFX_ByteString& sFontAlias, FX_INT32 nCharset)
{
	ASSERT(m_pAnnotDict != NULL);

	if (m_pAnnotDict->GetString("Subtype") == "Widget")
	{
		CPDF_Document* pDocument = GetDocument();
		ASSERT(pDocument != NULL);

		CPDF_Dictionary * pRootDict = pDocument->GetRoot();
		if (!pRootDict) return NULL;

		CPDF_Dictionary* pAcroFormDict = pRootDict->GetDict("AcroForm");
		if (!pAcroFormDict) return NULL;

		CPDF_Dictionary * pDRDict = pAcroFormDict->GetDict("DR");
		if (!pDRDict) return NULL;

		return FindResFontSameCharset(pDRDict, sFontAlias, nCharset);
	}

	return NULL;
}
예제 #8
0
DLLEXPORT FPDF_PAGE STDCALL FPDF_LoadPage(FPDF_DOCUMENT document, int page_index)
{
    if (document == NULL) return NULL;
    if (page_index < 0 || page_index >= FPDF_GetPageCount(document)) return NULL;
//	CPDF_Parser* pParser = (CPDF_Parser*)document;
    CPDF_Document* pDoc = (CPDF_Document*)document;
    if (pDoc == NULL) return NULL;
    CPDF_Dictionary* pDict = pDoc->GetPage(page_index);
    if (pDict == NULL) return NULL;
    CPDF_Page* pPage = FX_NEW CPDF_Page;
    pPage->Load(pDoc, pDict);
    try {
        pPage->ParseContent();
    }
    catch (...) {
        delete pPage;
        return NULL;
    }

//	CheckUnSupportError(pDoc, 0);

    return pPage;
}
예제 #9
0
CPDF_Font* CBA_FontMap::FindResFontSameCharset(CPDF_Dictionary* pResDict,
                                               CFX_ByteString& sFontAlias,
                                               int32_t nCharset) {
  if (!pResDict)
    return nullptr;

  CPDF_Dictionary* pFonts = pResDict->GetDictBy("Font");
  if (!pFonts)
    return nullptr;

  CPDF_Document* pDocument = GetDocument();
  CPDF_Font* pFind = nullptr;
  for (const auto& it : *pFonts) {
    const CFX_ByteString& csKey = it.first;
    CPDF_Object* pObj = it.second;
    if (!pObj)
      continue;

    CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect());
    if (!pElement)
      continue;
    if (pElement->GetStringBy("Type") != "Font")
      continue;

    CPDF_Font* pFont = pDocument->LoadFont(pElement);
    if (!pFont)
      continue;
    const CFX_SubstFont* pSubst = pFont->GetSubstFont();
    if (!pSubst)
      continue;
    if (pSubst->m_Charset == nCharset) {
      sFontAlias = csKey;
      pFind = pFont;
    }
  }
  return pFind;
}
예제 #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;
}
예제 #11
0
FX_BOOL Document::getPageNthWord(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
	ASSERT(m_pDocument != NULL);

	if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS)) return FALSE;

	int nPageNo = params.GetSize() > 0 ? params[0].ToInt() : 0;
	int nWordNo = params.GetSize() > 1 ? params[1].ToInt() : 0;
	bool bStrip = params.GetSize() > 2 ? params[2].ToBool() : true;

	CPDF_Document* pDocument = m_pDocument->GetDocument();
	if (!pDocument) return FALSE;

	CJS_Context* pContext = static_cast<CJS_Context*>(cc);
	if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
	{
		sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR);
		return FALSE;
	}

	CPDF_Dictionary* pPageDict = pDocument->GetPage(nPageNo);
	if (!pPageDict) return FALSE;

	CPDF_Page page;
	page.Load(pDocument, pPageDict);
	page.StartParse();
	page.ParseContent();

	FX_POSITION pos = page.GetFirstObjectPosition();

	int nWords = 0;

	CFX_WideString swRet;

	while (pos)
	{
		if (CPDF_PageObject* pPageObj = page.GetNextObject(pos))
		{
			if (pPageObj->m_Type == PDFPAGE_TEXT)
			{
				int nObjWords = CountWords((CPDF_TextObject*)pPageObj);

				if (nWords + nObjWords >= nWordNo)
				{
					swRet = GetObjWordStr((CPDF_TextObject*)pPageObj, nWordNo - nWords);
					break;
				}

				nWords += nObjWords;
			}
		}
	}

	if (bStrip)
	{
		swRet.TrimLeft();
		swRet.TrimRight();
	}

	vRet = swRet.c_str();
	return TRUE;
}
예제 #12
0
DLLEXPORT void STDCALL FPDFPage_InsertClipPath(FPDF_PAGE page,
                                               FPDF_CLIPPATH clipPath) {
  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
  if (!pPage)
    return;

  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;

  CFX_ByteTextBuf strClip;
  CPDF_ClipPath* pClipPath = (CPDF_ClipPath*)clipPath;
  FX_DWORD i;
  for (i = 0; i < pClipPath->GetPathCount(); i++) {
    CPDF_Path path = pClipPath->GetPath(i);
    int iClipType = pClipPath->GetClipType(i);
    if (path.GetPointCount() == 0) {
      // Empty clipping (totally clipped out)
      strClip << "0 0 m W n ";
    } else {
      OutputPath(strClip, path);
      if (iClipType == FXFILL_WINDING)
        strClip << "W n\n";
      else
        strClip << "W* n\n";
    }
  }
  CPDF_Dictionary* pDic = new CPDF_Dictionary;
  CPDF_Stream* pStream = new CPDF_Stream(nullptr, 0, pDic);
  pStream->SetData(strClip.GetBuffer(), strClip.GetSize(), FALSE, FALSE);
  CPDF_Document* pDoc = pPage->m_pDocument;
  if (!pDoc)
    return;
  pDoc->AddIndirectObject(pStream);

  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);
  } 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);
      } else if (pDirectObj->IsStream()) {
        pContentArray = new CPDF_Array();
        pContentArray->AddReference(pDoc, pStream->GetObjNum());
        pContentArray->AddReference(pDoc, pDirectObj->GetObjNum());
        pPageDic->SetAtReference("Contents", pDoc,
                                 pDoc->AddIndirectObject(pContentArray));
      }
    }
  }
}
예제 #13
0
FX_BOOL CPDF_RenderStatus::ProcessTransparency(CPDF_PageObject* pPageObj,
                                               const CFX_Matrix* pObj2Device) {
#if defined _SKIA_SUPPORT_
  DebugVerifyDeviceIsPreMultiplied();
#endif
  int blend_type = pPageObj->m_GeneralState.GetBlendType();
  if (blend_type == FXDIB_BLEND_UNSUPPORTED)
    return TRUE;

  CPDF_Dictionary* pSMaskDict =
      ToDictionary(pPageObj->m_GeneralState.GetSoftMask());
  if (pSMaskDict) {
    if (pPageObj->IsImage() &&
        pPageObj->AsImage()->GetImage()->GetDict()->KeyExist("SMask")) {
      pSMaskDict = nullptr;
    }
  }
  CPDF_Dictionary* pFormResource = nullptr;
  FX_FLOAT group_alpha = 1.0f;
  int Transparency = m_Transparency;
  FX_BOOL bGroupTransparent = FALSE;
  if (pPageObj->IsForm()) {
    const CPDF_FormObject* pFormObj = pPageObj->AsForm();
    group_alpha = pFormObj->m_GeneralState.GetFillAlpha();
    Transparency = pFormObj->m_pForm->m_Transparency;
    bGroupTransparent = !!(Transparency & PDFTRANS_ISOLATED);
    if (pFormObj->m_pForm->m_pFormDict) {
      pFormResource = pFormObj->m_pForm->m_pFormDict->GetDictBy("Resources");
    }
  }
  bool bTextClip =
      (pPageObj->m_ClipPath && pPageObj->m_ClipPath.GetTextCount() &&
       m_pDevice->GetDeviceClass() == FXDC_DISPLAY &&
       !(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP));
  if ((m_Options.m_Flags & RENDER_OVERPRINT) && pPageObj->IsImage() &&
      pPageObj->m_GeneralState.GetFillOP() &&
      pPageObj->m_GeneralState.GetStrokeOP()) {
    CPDF_Document* pDocument = nullptr;
    CPDF_Page* pPage = nullptr;
    if (m_pContext->GetPageCache()) {
      pPage = m_pContext->GetPageCache()->GetPage();
      pDocument = pPage->m_pDocument;
    } else {
      pDocument = pPageObj->AsImage()->GetImage()->GetDocument();
    }
    CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : nullptr;
    CPDF_Object* pCSObj = pPageObj->AsImage()
                              ->GetImage()
                              ->GetStream()
                              ->GetDict()
                              ->GetDirectObjectBy("ColorSpace");
    CPDF_ColorSpace* pColorSpace =
        pDocument->LoadColorSpace(pCSObj, pPageResources);
    if (pColorSpace) {
      int format = pColorSpace->GetFamily();
      if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION ||
          format == PDFCS_DEVICEN) {
        blend_type = FXDIB_BLEND_DARKEN;
      }
      pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
    }
  }
  if (!pSMaskDict && group_alpha == 1.0f && blend_type == FXDIB_BLEND_NORMAL &&
      !bTextClip && !bGroupTransparent) {
    return FALSE;
  }
  bool isolated = !!(Transparency & PDFTRANS_ISOLATED);
  if (m_bPrint) {
    FX_BOOL bRet = FALSE;
    int rendCaps = m_pDevice->GetRenderCaps();
    if (!((Transparency & PDFTRANS_ISOLATED) || pSMaskDict || bTextClip) &&
        (rendCaps & FXRC_BLEND_MODE)) {
      int oldBlend = m_curBlend;
      m_curBlend = blend_type;
      bRet = DrawObjWithBlend(pPageObj, pObj2Device);
      m_curBlend = oldBlend;
    }
    if (!bRet) {
      DrawObjWithBackground(pPageObj, pObj2Device);
    }
    return TRUE;
  }
  FX_RECT rect = pPageObj->GetBBox(pObj2Device);
  rect.Intersect(m_pDevice->GetClipBox());
  if (rect.IsEmpty()) {
    return TRUE;
  }
  CFX_Matrix deviceCTM = m_pDevice->GetCTM();
  FX_FLOAT scaleX = FXSYS_fabs(deviceCTM.a);
  FX_FLOAT scaleY = FXSYS_fabs(deviceCTM.d);
  int width = FXSYS_round((FX_FLOAT)rect.Width() * scaleX);
  int height = FXSYS_round((FX_FLOAT)rect.Height() * scaleY);
  CFX_FxgeDevice bitmap_device;
  std::unique_ptr<CFX_DIBitmap> oriDevice;
  if (!isolated && (m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) {
    oriDevice.reset(new CFX_DIBitmap);
    if (!m_pDevice->CreateCompatibleBitmap(oriDevice.get(), width, height))
      return TRUE;
    m_pDevice->GetDIBits(oriDevice.get(), rect.left, rect.top);
  }
  if (!bitmap_device.Create(width, height, FXDIB_Argb, oriDevice.get()))
    return TRUE;
  CFX_DIBitmap* bitmap = bitmap_device.GetBitmap();
  bitmap->Clear(0);
  CFX_Matrix new_matrix = *pObj2Device;
  new_matrix.TranslateI(-rect.left, -rect.top);
  new_matrix.Scale(scaleX, scaleY);
  std::unique_ptr<CFX_DIBitmap> pTextMask;
  if (bTextClip) {
    pTextMask.reset(new CFX_DIBitmap);
    if (!pTextMask->Create(width, height, FXDIB_8bppMask))
      return TRUE;

    pTextMask->Clear(0);
    CFX_FxgeDevice text_device;
    text_device.Attach(pTextMask.get(), false, nullptr, false);
    for (uint32_t i = 0; i < pPageObj->m_ClipPath.GetTextCount(); i++) {
      CPDF_TextObject* textobj = pPageObj->m_ClipPath.GetText(i);
      if (!textobj) {
        break;
      }
      CFX_Matrix text_matrix;
      textobj->GetTextMatrix(&text_matrix);
      CPDF_TextRenderer::DrawTextPath(
          &text_device, textobj->m_nChars, textobj->m_pCharCodes,
          textobj->m_pCharPos, textobj->m_TextState.GetFont(),
          textobj->m_TextState.GetFontSize(), &text_matrix, &new_matrix,
          textobj->m_GraphState.GetObject(), (FX_ARGB)-1, 0, nullptr, 0);
    }
  }
  CPDF_RenderStatus bitmap_render;
  bitmap_render.Initialize(m_pContext, &bitmap_device, nullptr, m_pStopObj,
                           nullptr, nullptr, &m_Options, 0, m_bDropObjects,
                           pFormResource, TRUE);
  bitmap_render.ProcessObjectNoClip(pPageObj, &new_matrix);
  m_bStopped = bitmap_render.m_bStopped;
  if (pSMaskDict) {
    CFX_Matrix smask_matrix = *pPageObj->m_GeneralState.GetSMaskMatrix();
    smask_matrix.Concat(*pObj2Device);
    std::unique_ptr<CFX_DIBSource> pSMaskSource(
        LoadSMask(pSMaskDict, &rect, &smask_matrix));
    if (pSMaskSource)
      bitmap->MultiplyAlpha(pSMaskSource.get());
  }
  if (pTextMask) {
    bitmap->MultiplyAlpha(pTextMask.get());
    pTextMask.reset();
  }
  int32_t blitAlpha = 255;
  if (Transparency & PDFTRANS_GROUP && group_alpha != 1.0f) {
    blitAlpha = (int32_t)(group_alpha * 255);
#ifndef _SKIA_SUPPORT_
    bitmap->MultiplyAlpha(blitAlpha);
    blitAlpha = 255;
#endif
  }
  Transparency = m_Transparency;
  if (pPageObj->IsForm()) {
    Transparency |= PDFTRANS_GROUP;
  }
  CompositeDIBitmap(bitmap, rect.left, rect.top, 0, blitAlpha, blend_type,
                    Transparency);
#if defined _SKIA_SUPPORT_
  DebugVerifyDeviceIsPreMultiplied();
#endif
  return TRUE;
}
예제 #14
0
DLLEXPORT int STDCALL FPDFAvail_GetFirstPageNum(FPDF_DOCUMENT doc) {
  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(doc);
  return pDoc ? pDoc->GetParser()->GetFirstPageNo() : 0;
}
예제 #15
0
DLLEXPORT void STDCALL FPDFPage_InsertClipPath(FPDF_PAGE page,FPDF_CLIPPATH clipPath)
{
	if(!page)
		return;
	CPDF_Page* pPage = (CPDF_Page*)page;
	CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
	CPDF_Object* pContentObj = pPageDic->GetElement("Contents");
	if(!pContentObj)
		pContentObj = pPageDic->GetArray("Contents");
	if(!pContentObj)
		return;

	CFX_ByteTextBuf strClip;
	CPDF_ClipPath* pClipPath = (CPDF_ClipPath*)clipPath;
	FX_DWORD i;
	for (i = 0; i < pClipPath->GetPathCount(); i ++) {
		CPDF_Path path = pClipPath->GetPath(i);
		int iClipType = pClipPath->GetClipType(i);
		if (path.GetPointCount() == 0) {
			// Empty clipping (totally clipped out)
			strClip << "0 0 m W n ";
		} else {
			OutputPath(strClip, path);
			if (iClipType == FXFILL_WINDING)
				strClip << "W n\n";
			else
				strClip << "W* n\n";
		}
	}
	CPDF_Dictionary* pDic = FX_NEW CPDF_Dictionary;
	CPDF_Stream* pStream = FX_NEW CPDF_Stream(NULL,0, pDic);
	pStream->SetData(strClip.GetBuffer(), strClip.GetSize(), FALSE, FALSE);
	CPDF_Document* pDoc = pPage->m_pDocument;
	if(!pDoc)
		return;
	pDoc->AddIndirectObject(pStream);
	
	CPDF_Array* pContentArray = NULL;
	if (pContentObj && pContentObj->GetType() == PDFOBJ_ARRAY)
	{
		pContentArray = (CPDF_Array*)pContentObj;
		CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
		pContentArray->InsertAt(0, pRef);
		
	}
	else if(pContentObj && pContentObj->GetType() == PDFOBJ_REFERENCE)
	{
		CPDF_Reference* pReference = (CPDF_Reference*)pContentObj;
		CPDF_Object* pDirectObj = pReference->GetDirect();
		if(pDirectObj != NULL)
		{
			if(pDirectObj->GetType() == PDFOBJ_ARRAY)
			{
				pContentArray = (CPDF_Array*)pDirectObj;
				CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
				pContentArray->InsertAt(0, pRef);
				
			}
			else if(pDirectObj->GetType() == PDFOBJ_STREAM)
			{
				pContentArray = FX_NEW CPDF_Array();
				pContentArray->AddReference(pDoc,pStream->GetObjNum());
				pContentArray->AddReference(pDoc,pDirectObj->GetObjNum());
				pPageDic->SetAtReference("Contents", pDoc, pDoc->AddIndirectObject(pContentArray));
			}
		}
	}	
}
예제 #16
0
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_TransFormWithClip(FPDF_PAGE page, FS_MATRIX* matrix, FS_RECTF* clipRect)
{
	if(!page)
		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_Page* pPage = (CPDF_Page*)page;
	CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
	CPDF_Object* pContentObj = pPageDic->GetElement("Contents");
	if(!pContentObj)
		pContentObj = pPageDic->GetArray("Contents");
	if(!pContentObj)
		return FALSE;
	
	CPDF_Dictionary* pDic = FX_NEW CPDF_Dictionary;
	CPDF_Stream* pStream = FX_NEW CPDF_Stream(NULL,0, pDic);
	pStream->SetData(textBuf.GetBuffer(), textBuf.GetSize(), FALSE, FALSE);
	CPDF_Document* pDoc = pPage->m_pDocument;
	if(!pDoc)
		return FALSE;
	pDoc->AddIndirectObject(pStream);

	pDic = FX_NEW CPDF_Dictionary;
	CPDF_Stream* pEndStream = FX_NEW CPDF_Stream(NULL,0, pDic);
	pEndStream->SetData((FX_LPCBYTE)" Q", 2, FALSE, FALSE);
	pDoc->AddIndirectObject(pEndStream);
	
	CPDF_Array* pContentArray = NULL;
	if (pContentObj && pContentObj->GetType() == PDFOBJ_ARRAY)
	{
		pContentArray = (CPDF_Array*)pContentObj;
		CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
		pContentArray->InsertAt(0, pRef);
		pContentArray->AddReference(pDoc,pEndStream);
		
	}
	else if(pContentObj && pContentObj->GetType() == PDFOBJ_REFERENCE)
	{
		CPDF_Reference* pReference = (CPDF_Reference*)pContentObj;
		CPDF_Object* pDirectObj = pReference->GetDirect();
		if(pDirectObj != NULL)
		{
			if(pDirectObj->GetType() == PDFOBJ_ARRAY)
			{
				pContentArray = (CPDF_Array*)pDirectObj;
				CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
				pContentArray->InsertAt(0, pRef);
				pContentArray->AddReference(pDoc,pEndStream);
				
			}
			else if(pDirectObj->GetType() == PDFOBJ_STREAM)
			{
				pContentArray = FX_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->GetDict(FX_BSTRC("Resources"));
	if(pRes)
	{
		CPDF_Dictionary* pPattenDict = pRes->GetDict(FX_BSTRC("Pattern"));
		if(pPattenDict)
		{
			FX_POSITION pos = pPattenDict->GetStartPos();
			while(pos)
			{
				CPDF_Dictionary* pDict = NULL;
				CFX_ByteString key;
				CPDF_Object* pObj = pPattenDict->GetNextElement(pos, key);
				if(pObj->GetType() == PDFOBJ_REFERENCE)
					pObj = pObj->GetDirect();
				if(pObj->GetType() == PDFOBJ_DICTIONARY)
				{
					pDict = (CPDF_Dictionary*)pObj;
				}
				else if(pObj->GetType() == PDFOBJ_STREAM)
				{
					pDict = ((CPDF_Stream*)pObj)->GetDict();
				}
				else
					continue;
				
				CFX_AffineMatrix m = pDict->GetMatrix(FX_BSTRC("Matrix"));
				CFX_AffineMatrix t = *(CFX_AffineMatrix*)matrix;
				m.Concat(t);
				pDict->SetAtMatrix(FX_BSTRC("Matrix"), m);
			}
		}
	}

	return TRUE;
}
예제 #17
0
DLLEXPORT int STDCALL FPDFAvail_GetFirstPageNum(FPDF_DOCUMENT doc)
{
	if (doc == NULL) return 0;
	CPDF_Document* pDoc = (CPDF_Document*)doc;
	return ((CPDF_Parser*)pDoc->GetParser())->GetFirstPageNo();
}
예제 #18
0
bool CPDF_ImageRenderer::StartRenderDIBSource() {
  if (!m_Loader.m_pBitmap)
    return false;

  m_BitmapAlpha =
      FXSYS_round(255 * m_pImageObject->m_GeneralState.GetFillAlpha());
  m_pDIBSource = m_Loader.m_pBitmap;
  if (m_pRenderStatus->m_Options.m_ColorMode == RENDER_COLOR_ALPHA &&
      !m_Loader.m_pMask) {
    return StartBitmapAlpha();
  }
  if (m_pImageObject->m_GeneralState.GetTR()) {
    if (!m_pImageObject->m_GeneralState.GetTransferFunc()) {
      m_pImageObject->m_GeneralState.SetTransferFunc(
          m_pRenderStatus->GetTransferFunc(
              m_pImageObject->m_GeneralState.GetTR()));
    }
    if (m_pImageObject->m_GeneralState.GetTransferFunc() &&
        !m_pImageObject->m_GeneralState.GetTransferFunc()->m_bIdentity) {
      m_pDIBSource = m_Loader.m_pBitmap =
          m_pImageObject->m_GeneralState.GetTransferFunc()->TranslateImage(
              m_Loader.m_pBitmap, !m_Loader.m_bCached);
      if (m_Loader.m_bCached && m_Loader.m_pMask)
        m_Loader.m_pMask = m_Loader.m_pMask->Clone().release();
      m_Loader.m_bCached = false;
    }
  }
  m_FillArgb = 0;
  m_bPatternColor = false;
  m_pPattern = nullptr;
  if (m_pDIBSource->IsAlphaMask()) {
    const CPDF_Color* pColor = m_pImageObject->m_ColorState.GetFillColor();
    if (pColor && pColor->IsPattern()) {
      m_pPattern = pColor->GetPattern();
      if (m_pPattern)
        m_bPatternColor = true;
    }
    m_FillArgb = m_pRenderStatus->GetFillArgb(m_pImageObject);
  } else if (m_pRenderStatus->m_Options.m_ColorMode == RENDER_COLOR_GRAY) {
    m_pClone = m_pDIBSource->Clone();
    m_pClone->ConvertColorScale(m_pRenderStatus->m_Options.m_BackColor,
                                m_pRenderStatus->m_Options.m_ForeColor);
    m_pDIBSource = m_pClone.get();
  }
  m_Flags = 0;
  if (m_pRenderStatus->m_Options.m_Flags & RENDER_FORCE_DOWNSAMPLE)
    m_Flags |= RENDER_FORCE_DOWNSAMPLE;
  else if (m_pRenderStatus->m_Options.m_Flags & RENDER_FORCE_HALFTONE)
    m_Flags |= RENDER_FORCE_HALFTONE;
  if (m_pRenderStatus->m_pDevice->GetDeviceClass() != FXDC_DISPLAY) {
    CPDF_Object* pFilters =
        m_pImageObject->GetImage()->GetStream()->GetDict()->GetDirectObjectFor(
            "Filter");
    if (pFilters) {
      if (pFilters->IsName()) {
        CFX_ByteString bsDecodeType = pFilters->GetString();
        if (bsDecodeType == "DCTDecode" || bsDecodeType == "JPXDecode")
          m_Flags |= FXRENDER_IMAGE_LOSSY;
      } else if (CPDF_Array* pArray = pFilters->AsArray()) {
        for (size_t i = 0; i < pArray->GetCount(); i++) {
          CFX_ByteString bsDecodeType = pArray->GetStringAt(i);
          if (bsDecodeType == "DCTDecode" || bsDecodeType == "JPXDecode") {
            m_Flags |= FXRENDER_IMAGE_LOSSY;
            break;
          }
        }
      }
    }
  }
  if (m_pRenderStatus->m_Options.m_Flags & RENDER_NOIMAGESMOOTH)
    m_Flags |= FXDIB_NOSMOOTH;
  else if (m_pImageObject->GetImage()->IsInterpol())
    m_Flags |= FXDIB_INTERPOL;
  if (m_Loader.m_pMask)
    return DrawMaskedImage();

  if (m_bPatternColor)
    return DrawPatternImage(m_pObj2Device);

  if (m_BitmapAlpha != 255 || !m_pImageObject->m_GeneralState ||
      !m_pImageObject->m_GeneralState.GetFillOP() ||
      m_pImageObject->m_GeneralState.GetOPMode() != 0 ||
      m_pImageObject->m_GeneralState.GetBlendType() != FXDIB_BLEND_NORMAL ||
      m_pImageObject->m_GeneralState.GetStrokeAlpha() != 1.0f ||
      m_pImageObject->m_GeneralState.GetFillAlpha() != 1.0f) {
    return StartDIBSource();
  }
  CPDF_Document* pDocument = nullptr;
  CPDF_Page* pPage = nullptr;
  if (m_pRenderStatus->m_pContext->GetPageCache()) {
    pPage = m_pRenderStatus->m_pContext->GetPageCache()->GetPage();
    pDocument = pPage->m_pDocument;
  } else {
    pDocument = m_pImageObject->GetImage()->GetDocument();
  }
  CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : nullptr;
  CPDF_Object* pCSObj =
      m_pImageObject->GetImage()->GetStream()->GetDict()->GetDirectObjectFor(
          "ColorSpace");
  CPDF_ColorSpace* pColorSpace =
      pDocument->LoadColorSpace(pCSObj, pPageResources);
  if (!pColorSpace)
    return StartDIBSource();
  int format = pColorSpace->GetFamily();
  if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION ||
      format == PDFCS_DEVICEN) {
    m_BlendType = FXDIB_BLEND_DARKEN;
  }
  pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
  return StartDIBSource();
}
예제 #19
0
FX_BOOL CPDF_RenderStatus::ProcessTransparency(
    const CPDF_PageObject* pPageObj,
    const CFX_AffineMatrix* pObj2Device) {
  const CPDF_GeneralStateData* pGeneralState = pPageObj->m_GeneralState;
  int blend_type =
      pGeneralState ? pGeneralState->m_BlendType : FXDIB_BLEND_NORMAL;
  if (blend_type == FXDIB_BLEND_UNSUPPORTED) {
    return TRUE;
  }
  CPDF_Dictionary* pSMaskDict =
      pGeneralState ? ToDictionary(pGeneralState->m_pSoftMask) : NULL;
  if (pSMaskDict) {
    if (pPageObj->m_Type == PDFPAGE_IMAGE &&
        ((CPDF_ImageObject*)pPageObj)
            ->m_pImage->GetDict()
            ->KeyExist(FX_BSTRC("SMask"))) {
      pSMaskDict = NULL;
    }
  }
  CPDF_Dictionary* pFormResource = NULL;
  FX_FLOAT group_alpha = 1.0f;
  int Transparency = m_Transparency;
  FX_BOOL bGroupTransparent = FALSE;
  if (pPageObj->m_Type == PDFPAGE_FORM) {
    CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj;
    const CPDF_GeneralStateData* pStateData =
        pFormObj->m_GeneralState.GetObject();
    if (pStateData) {
      group_alpha = pStateData->m_FillAlpha;
    }
    Transparency = pFormObj->m_pForm->m_Transparency;
    bGroupTransparent = !!(Transparency & PDFTRANS_ISOLATED);
    if (pFormObj->m_pForm->m_pFormDict) {
      pFormResource = pFormObj->m_pForm->m_pFormDict->GetDict("Resources");
    }
  }
  FX_BOOL bTextClip = FALSE;
  if (pPageObj->m_ClipPath.NotNull() && pPageObj->m_ClipPath.GetTextCount() &&
      m_pDevice->GetDeviceClass() == FXDC_DISPLAY &&
      !(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP)) {
    bTextClip = TRUE;
  }
  if ((m_Options.m_Flags & RENDER_OVERPRINT) &&
      pPageObj->m_Type == PDFPAGE_IMAGE && pGeneralState &&
      pGeneralState->m_FillOP && pGeneralState->m_StrokeOP) {
    CPDF_Document* pDocument = NULL;
    CPDF_Page* pPage = NULL;
    if (m_pContext->m_pPageCache) {
      pPage = m_pContext->m_pPageCache->GetPage();
      pDocument = pPage->m_pDocument;
    } else {
      pDocument = ((CPDF_ImageObject*)pPageObj)->m_pImage->GetDocument();
    }
    CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : NULL;
    CPDF_Object* pCSObj = ((CPDF_ImageObject*)pPageObj)
                              ->m_pImage->GetStream()
                              ->GetDict()
                              ->GetElementValue(FX_BSTRC("ColorSpace"));
    CPDF_ColorSpace* pColorSpace =
        pDocument->LoadColorSpace(pCSObj, pPageResources);
    if (pColorSpace) {
      int format = pColorSpace->GetFamily();
      if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION ||
          format == PDFCS_DEVICEN) {
        blend_type = FXDIB_BLEND_DARKEN;
      }
      pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
    }
  }
  if (pSMaskDict == NULL && group_alpha == 1.0f &&
      blend_type == FXDIB_BLEND_NORMAL && !bTextClip && !bGroupTransparent) {
    return FALSE;
  }
  FX_BOOL isolated = Transparency & PDFTRANS_ISOLATED;
  if (m_bPrint) {
    FX_BOOL bRet = FALSE;
    int rendCaps = m_pDevice->GetRenderCaps();
    if (!((Transparency & PDFTRANS_ISOLATED) || pSMaskDict || bTextClip) &&
        (rendCaps & FXRC_BLEND_MODE)) {
      int oldBlend = m_curBlend;
      m_curBlend = blend_type;
      bRet = DrawObjWithBlend(pPageObj, pObj2Device);
      m_curBlend = oldBlend;
    }
    if (!bRet) {
      DrawObjWithBackground(pPageObj, pObj2Device);
    }
    return TRUE;
  }
  FX_RECT rect = pPageObj->GetBBox(pObj2Device);
  rect.Intersect(m_pDevice->GetClipBox());
  if (rect.IsEmpty()) {
    return TRUE;
  }
  CFX_Matrix deviceCTM = m_pDevice->GetCTM();
  FX_FLOAT scaleX = FXSYS_fabs(deviceCTM.a);
  FX_FLOAT scaleY = FXSYS_fabs(deviceCTM.d);
  int width = FXSYS_round((FX_FLOAT)rect.Width() * scaleX);
  int height = FXSYS_round((FX_FLOAT)rect.Height() * scaleY);
  CFX_FxgeDevice bitmap_device;
  nonstd::unique_ptr<CFX_DIBitmap> oriDevice;
  if (!isolated && (m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) {
    oriDevice.reset(new CFX_DIBitmap);
    if (!m_pDevice->CreateCompatibleBitmap(oriDevice.get(), width, height))
      return TRUE;

    m_pDevice->GetDIBits(oriDevice.get(), rect.left, rect.top);
  }
  if (!bitmap_device.Create(width, height, FXDIB_Argb, 0, oriDevice.get()))
    return TRUE;

  CFX_DIBitmap* bitmap = bitmap_device.GetBitmap();
  bitmap->Clear(0);
  CFX_AffineMatrix new_matrix = *pObj2Device;
  new_matrix.TranslateI(-rect.left, -rect.top);
  new_matrix.Scale(scaleX, scaleY);
  nonstd::unique_ptr<CFX_DIBitmap> pTextMask;
  if (bTextClip) {
    pTextMask.reset(new CFX_DIBitmap);
    if (!pTextMask->Create(width, height, FXDIB_8bppMask))
      return TRUE;

    pTextMask->Clear(0);
    CFX_FxgeDevice text_device;
    text_device.Attach(pTextMask.get());
    for (FX_DWORD i = 0; i < pPageObj->m_ClipPath.GetTextCount(); i++) {
      CPDF_TextObject* textobj = pPageObj->m_ClipPath.GetText(i);
      if (textobj == NULL) {
        break;
      }
      CFX_AffineMatrix text_matrix;
      textobj->GetTextMatrix(&text_matrix);
      CPDF_TextRenderer::DrawTextPath(
          &text_device, textobj->m_nChars, textobj->m_pCharCodes,
          textobj->m_pCharPos, textobj->m_TextState.GetFont(),
          textobj->m_TextState.GetFontSize(), &text_matrix, &new_matrix,
          textobj->m_GraphState, (FX_ARGB)-1, 0, NULL);
    }
  }
  CPDF_RenderStatus bitmap_render;
  bitmap_render.Initialize(m_pContext, &bitmap_device, NULL, m_pStopObj, NULL,
                           NULL, &m_Options, 0, m_bDropObjects, pFormResource,
                           TRUE);
  bitmap_render.ProcessObjectNoClip(pPageObj, &new_matrix);
  m_bStopped = bitmap_render.m_bStopped;
  if (pSMaskDict) {
    CFX_AffineMatrix smask_matrix;
    FXSYS_memcpy(&smask_matrix, pGeneralState->m_SMaskMatrix,
                 sizeof smask_matrix);
    smask_matrix.Concat(*pObj2Device);
    nonstd::unique_ptr<CFX_DIBSource> pSMaskSource(
        LoadSMask(pSMaskDict, &rect, &smask_matrix));
    if (pSMaskSource)
      bitmap->MultiplyAlpha(pSMaskSource.get());
  }
  if (pTextMask) {
    bitmap->MultiplyAlpha(pTextMask.get());
    pTextMask.reset();
  }
  if (Transparency & PDFTRANS_GROUP && group_alpha != 1.0f) {
    bitmap->MultiplyAlpha((int32_t)(group_alpha * 255));
  }
  Transparency = m_Transparency;
  if (pPageObj->m_Type == PDFPAGE_FORM) {
    Transparency |= PDFTRANS_GROUP;
  }
  CompositeDIBitmap(bitmap, rect.left, rect.top, 0, 255, blend_type,
                    Transparency);
  return TRUE;
}
예제 #20
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;
}
예제 #21
0
DLLEXPORT void STDCALL FPDFPage_InsertClipPath(FPDF_PAGE page,
                                               FPDF_CLIPPATH clipPath) {
  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
  if (!pPage)
    return;

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

  CFX_ByteTextBuf strClip;
  CPDF_ClipPath* pClipPath = (CPDF_ClipPath*)clipPath;
  uint32_t i;
  for (i = 0; i < pClipPath->GetPathCount(); i++) {
    CPDF_Path path = pClipPath->GetPath(i);
    int iClipType = pClipPath->GetClipType(i);
    if (path.GetPoints().empty()) {
      // Empty clipping (totally clipped out)
      strClip << "0 0 m W n ";
    } else {
      OutputPath(strClip, path);
      if (iClipType == FXFILL_WINDING)
        strClip << "W n\n";
      else
        strClip << "W* n\n";
    }
  }
  CPDF_Document* pDoc = pPage->m_pDocument;
  if (!pDoc)
    return;

  CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>(
      nullptr, 0,
      pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()));
  pStream->SetData(strClip.GetBuffer(), strClip.GetSize());

  CPDF_Array* pArray = ToArray(pContentObj);
  if (pArray) {
    pArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
    return;
  }
  CPDF_Reference* pReference = ToReference(pContentObj);
  if (!pReference)
    return;

  CPDF_Object* pDirectObj = pReference->GetDirect();
  if (!pDirectObj)
    return;

  CPDF_Array* pObjArray = pDirectObj->AsArray();
  if (pObjArray) {
    pObjArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
    return;
  }
  if (pDirectObj->IsStream()) {
    CPDF_Array* pContentArray = pDoc->NewIndirect<CPDF_Array>();
    pContentArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
    pContentArray->AddNew<CPDF_Reference>(pDoc, pDirectObj->GetObjNum());
    pPageDic->SetNewFor<CPDF_Reference>("Contents", pDoc,
                                        pContentArray->GetObjNum());
  }
}
예제 #22
0
FX_BOOL _SaveXFADocumentData(CPDFXFA_Document* pDocument,
                             CFX_PtrArray& fileList) {
  if (!pDocument)
    return FALSE;
  if (pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
      pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
    return TRUE;
  if (!CPDFXFA_App::GetInstance()->GetXFAApp())
    return TRUE;

  IXFA_DocView* pXFADocView = pDocument->GetXFADocView();
  if (NULL == pXFADocView)
    return TRUE;

  IXFA_DocHandler* pXFADocHandler =
      CPDFXFA_App::GetInstance()->GetXFAApp()->GetDocHandler();
  CPDF_Document* pPDFDocument = pDocument->GetPDFDoc();
  if (pDocument == NULL)
    return FALSE;

  CPDF_Dictionary* pRoot = pPDFDocument->GetRoot();
  if (pRoot == NULL)
    return FALSE;
  CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm");
  if (NULL == pAcroForm)
    return FALSE;
  CPDF_Object* pXFA = pAcroForm->GetElement("XFA");
  if (pXFA == NULL)
    return TRUE;
  if (pXFA->GetType() != PDFOBJ_ARRAY)
    return FALSE;
  CPDF_Array* pArray = pXFA->GetArray();
  if (NULL == pArray)
    return FALSE;
  int size = pArray->GetCount();
  int iFormIndex = -1;
  int iDataSetsIndex = -1;
  int iTemplate = -1;
  int iLast = size - 2;
  for (int i = 0; i < size - 1; i++) {
    CPDF_Object* pPDFObj = pArray->GetElement(i);
    if (pPDFObj->GetType() != PDFOBJ_STRING)
      continue;
    if (pPDFObj->GetString() == "form")
      iFormIndex = i + 1;
    else if (pPDFObj->GetString() == "datasets")
      iDataSetsIndex = i + 1;
    else if (pPDFObj->GetString() == "template")
      iTemplate = i + 1;
  }
  IXFA_ChecksumContext* pContext = NULL;
  // Checksum
  pContext = XFA_Checksum_Create();
  FXSYS_assert(pContext);
  pContext->StartChecksum();

  // template
  if (iTemplate > -1) {
    CPDF_Stream* pTemplateStream = pArray->GetStream(iTemplate);
    CPDF_StreamAcc streamAcc;
    streamAcc.LoadAllData(pTemplateStream);
    uint8_t* pData = (uint8_t*)streamAcc.GetData();
    FX_DWORD dwSize2 = streamAcc.GetSize();
    IFX_FileStream* pTemplate = FX_CreateMemoryStream(pData, dwSize2);
    pContext->UpdateChecksum((IFX_FileRead*)pTemplate);
    pTemplate->Release();
  }
  CPDF_Stream* pFormStream = NULL;
  CPDF_Stream* pDataSetsStream = NULL;
  if (iFormIndex != -1) {
    // Get form CPDF_Stream
    CPDF_Object* pFormPDFObj = pArray->GetElement(iFormIndex);
    if (pFormPDFObj->GetType() == PDFOBJ_REFERENCE) {
      CPDF_Object* pFormDircetObj = pFormPDFObj->GetDirect();
      if (NULL != pFormDircetObj &&
          pFormDircetObj->GetType() == PDFOBJ_STREAM) {
        pFormStream = (CPDF_Stream*)pFormDircetObj;
      }
    } else if (pFormPDFObj->GetType() == PDFOBJ_STREAM) {
      pFormStream = (CPDF_Stream*)pFormPDFObj;
    }
  }

  if (iDataSetsIndex != -1) {
    // Get datasets CPDF_Stream
    CPDF_Object* pDataSetsPDFObj = pArray->GetElement(iDataSetsIndex);
    if (pDataSetsPDFObj->GetType() == PDFOBJ_REFERENCE) {
      CPDF_Reference* pDataSetsRefObj = (CPDF_Reference*)pDataSetsPDFObj;
      CPDF_Object* pDataSetsDircetObj = pDataSetsRefObj->GetDirect();
      if (NULL != pDataSetsDircetObj &&
          pDataSetsDircetObj->GetType() == PDFOBJ_STREAM) {
        pDataSetsStream = (CPDF_Stream*)pDataSetsDircetObj;
      }
    } else if (pDataSetsPDFObj->GetType() == PDFOBJ_STREAM) {
      pDataSetsStream = (CPDF_Stream*)pDataSetsPDFObj;
    }
  }
  // end
  // L"datasets"
  {
    IFX_FileStream* pDsfileWrite = FX_CreateMemoryStream();
    if (NULL == pDsfileWrite) {
      pContext->Release();
      pDsfileWrite->Release();
      return FALSE;
    }
    if (pXFADocHandler->SavePackage(pXFADocView->GetDoc(),
                                    CFX_WideStringC(L"datasets"),
                                    pDsfileWrite) &&
        pDsfileWrite->GetSize() > 0) {
      // Datasets
      pContext->UpdateChecksum((IFX_FileRead*)pDsfileWrite);
      pContext->FinishChecksum();
      CPDF_Dictionary* pDataDict = new CPDF_Dictionary;
      if (iDataSetsIndex != -1) {
        if (pDataSetsStream)
          pDataSetsStream->InitStreamFromFile(pDsfileWrite, pDataDict);
      } else {
        CPDF_Stream* pData = new CPDF_Stream(NULL, 0, NULL);
        pData->InitStreamFromFile(pDsfileWrite, pDataDict);
        pPDFDocument->AddIndirectObject(pData);
        iLast = pArray->GetCount() - 2;
        pArray->InsertAt(iLast, new CPDF_String("datasets", FALSE));
        pArray->InsertAt(iLast + 1, pData, pPDFDocument);
      }
      fileList.Add(pDsfileWrite);
    }
  }

  // L"form"
  {
    IFX_FileStream* pfileWrite = FX_CreateMemoryStream();
    if (NULL == pfileWrite) {
      pContext->Release();
      return FALSE;
    }
    if (pXFADocHandler->SavePackage(pXFADocView->GetDoc(),
                                    CFX_WideStringC(L"form"), pfileWrite,
                                    pContext) &&
        pfileWrite > 0) {
      CPDF_Dictionary* pDataDict = new CPDF_Dictionary;
      if (iFormIndex != -1) {
        if (pFormStream)
          pFormStream->InitStreamFromFile(pfileWrite, pDataDict);
      } else {
        CPDF_Stream* pData = new CPDF_Stream(NULL, 0, NULL);
        pData->InitStreamFromFile(pfileWrite, pDataDict);
        pPDFDocument->AddIndirectObject(pData);
        iLast = pArray->GetCount() - 2;
        pArray->InsertAt(iLast, new CPDF_String("form", FALSE));
        pArray->InsertAt(iLast + 1, pData, pPDFDocument);
      }
      fileList.Add(pfileWrite);
    }
  }
  pContext->Release();
  return TRUE;
}
예제 #23
0
FX_BOOL CPDF_ImageRenderer::StartRenderDIBSource() {
    if (m_Loader.m_pBitmap == NULL) {
        return FALSE;
    }
    m_BitmapAlpha = 255;
    const CPDF_GeneralStateData* pGeneralState = m_pImageObject->m_GeneralState;
    if (pGeneralState) {
        m_BitmapAlpha = FXSYS_round(pGeneralState->m_FillAlpha * 255);
    }
    m_pDIBSource = m_Loader.m_pBitmap;
    if (m_pRenderStatus->m_Options.m_ColorMode == RENDER_COLOR_ALPHA &&
            m_Loader.m_pMask == NULL) {
        return StartBitmapAlpha();
    }
    if (pGeneralState && pGeneralState->m_pTR) {
        if (!pGeneralState->m_pTransferFunc) {
            ((CPDF_GeneralStateData*)pGeneralState)->m_pTransferFunc =
                m_pRenderStatus->GetTransferFunc(pGeneralState->m_pTR);
        }
        if (pGeneralState->m_pTransferFunc &&
                !pGeneralState->m_pTransferFunc->m_bIdentity) {
            m_pDIBSource = m_Loader.m_pBitmap =
                               pGeneralState->m_pTransferFunc->TranslateImage(m_Loader.m_pBitmap,
                                       !m_Loader.m_bCached);
            if (m_Loader.m_bCached && m_Loader.m_pMask) {
                m_Loader.m_pMask = m_Loader.m_pMask->Clone();
            }
            m_Loader.m_bCached = FALSE;
        }
    }
    m_FillArgb = 0;
    m_bPatternColor = FALSE;
    m_pPattern = NULL;
    if (m_pDIBSource->IsAlphaMask()) {
        CPDF_Color* pColor = m_pImageObject->m_ColorState.GetFillColor();
        if (pColor && pColor->IsPattern()) {
            m_pPattern = pColor->GetPattern();
            if (m_pPattern != NULL) {
                m_bPatternColor = TRUE;
            }
        }
        m_FillArgb = m_pRenderStatus->GetFillArgb(m_pImageObject);
    } else if (m_pRenderStatus->m_Options.m_ColorMode == RENDER_COLOR_GRAY) {
        m_pClone = m_pDIBSource->Clone();
        m_pClone->ConvertColorScale(m_pRenderStatus->m_Options.m_BackColor,
                                    m_pRenderStatus->m_Options.m_ForeColor);
        m_pDIBSource = m_pClone;
    }
    m_Flags = 0;
    if (m_pRenderStatus->m_Options.m_Flags & RENDER_FORCE_DOWNSAMPLE) {
        m_Flags |= RENDER_FORCE_DOWNSAMPLE;
    } else if (m_pRenderStatus->m_Options.m_Flags & RENDER_FORCE_HALFTONE) {
        m_Flags |= RENDER_FORCE_HALFTONE;
    }
    if (m_pRenderStatus->m_pDevice->GetDeviceClass() != FXDC_DISPLAY) {
        CPDF_Object* pFilters =
            m_pImageObject->m_pImage->GetStream()->GetDict()->GetElementValue(
                FX_BSTRC("Filter"));
        if (pFilters) {
            if (pFilters->IsName()) {
                CFX_ByteStringC bsDecodeType = pFilters->GetConstString();
                if (bsDecodeType == FX_BSTRC("DCTDecode") ||
                        bsDecodeType == FX_BSTRC("JPXDecode")) {
                    m_Flags |= FXRENDER_IMAGE_LOSSY;
                }
            } else if (CPDF_Array* pArray = pFilters->AsArray()) {
                for (FX_DWORD i = 0; i < pArray->GetCount(); i++) {
                    CFX_ByteStringC bsDecodeType = pArray->GetConstString(i);
                    if (bsDecodeType == FX_BSTRC("DCTDecode") ||
                            bsDecodeType == FX_BSTRC("JPXDecode")) {
                        m_Flags |= FXRENDER_IMAGE_LOSSY;
                        break;
                    }
                }
            }
        }
    }
    if (m_pRenderStatus->m_Options.m_Flags & RENDER_NOIMAGESMOOTH) {
        m_Flags |= FXDIB_NOSMOOTH;
    } else if (m_pImageObject->m_pImage->IsInterpol()) {
        m_Flags |= FXDIB_INTERPOL;
    }
    if (m_Loader.m_pMask) {
        return DrawMaskedImage();
    }
    if (m_bPatternColor) {
        return DrawPatternImage(m_pObj2Device);
    }
    if (m_BitmapAlpha == 255 && pGeneralState && pGeneralState->m_FillOP &&
            pGeneralState->m_OPMode == 0 &&
            pGeneralState->m_BlendType == FXDIB_BLEND_NORMAL &&
            pGeneralState->m_StrokeAlpha == 1 && pGeneralState->m_FillAlpha == 1) {
        CPDF_Document* pDocument = NULL;
        CPDF_Page* pPage = NULL;
        if (m_pRenderStatus->m_pContext->m_pPageCache) {
            pPage = m_pRenderStatus->m_pContext->m_pPageCache->GetPage();
            pDocument = pPage->m_pDocument;
        } else {
            pDocument = m_pImageObject->m_pImage->GetDocument();
        }
        CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : NULL;
        CPDF_Object* pCSObj =
            m_pImageObject->m_pImage->GetStream()->GetDict()->GetElementValue(
                FX_BSTRC("ColorSpace"));
        CPDF_ColorSpace* pColorSpace =
            pDocument->LoadColorSpace(pCSObj, pPageResources);
        if (pColorSpace) {
            int format = pColorSpace->GetFamily();
            if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION ||
                    format == PDFCS_DEVICEN) {
                m_BlendType = FXDIB_BLEND_DARKEN;
            }
            pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
        }
    }
    return StartDIBSource();
}
예제 #24
0
DLLEXPORT int STDCALL FPDFPage_Flatten( FPDF_PAGE page, int nFlag)
{
	if (!page)
	{
		return FLATTEN_FAIL;
	}

	CPDF_Page * pPage = (CPDF_Page*)( page );
	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_NOTINGTODO)
	{
		return FLATTEN_NOTINGTODO;
	}else if (iRet == FLATTEN_FAIL)
	{
		return FLATTEN_FAIL;
	}
	
	CPDF_Rect rcOriginalCB;
	CPDF_Rect rcMerger = CalculateRect( &RectArray );
	CPDF_Rect rcOriginalMB = pPageDict->GetRect("MediaBox");

	if (pPageDict->KeyExist("CropBox"))
		rcOriginalMB = pPageDict->GetRect("CropBox");
	
	if (rcOriginalMB.IsEmpty()) 	
	{
		rcOriginalMB = CPDF_Rect(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->GetRect("ArtBox");
	else
		rcOriginalCB = rcOriginalMB;

	if (!rcOriginalMB.IsEmpty())
	{
		CPDF_Array* pMediaBox = FX_NEW CPDF_Array();	

		pMediaBox->Add(FX_NEW CPDF_Number(rcOriginalMB.left));
		pMediaBox->Add(FX_NEW CPDF_Number(rcOriginalMB.bottom));
		pMediaBox->Add(FX_NEW CPDF_Number(rcOriginalMB.right));
		pMediaBox->Add(FX_NEW CPDF_Number(rcOriginalMB.top));

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

	CPDF_Dictionary* pRes = NULL;
	pRes = pPageDict->GetDict("Resources");
	if (!pRes)
	{
		pRes = FX_NEW CPDF_Dictionary;
		pPageDict->SetAt( "Resources", pRes );
	}

	CPDF_Stream* pNewXObject = FX_NEW CPDF_Stream(NULL, 0, FX_NEW CPDF_Dictionary);
	FX_DWORD dwObjNum = pDocument->AddIndirectObject(pNewXObject);
	CPDF_Dictionary* pPageXObject = pRes->GetDict("XObject");
	if (!pPageXObject)
	{
		pPageXObject = FX_NEW CPDF_Dictionary;
		pRes->SetAt("XObject", pPageXObject);
	}

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

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

			if (!pPageXObject->KeyExist(key))
				break;
		}
	}

	SetPageContents(key, pPageDict, pDocument);

	CPDF_Dictionary* pNewXORes = NULL;

	if (!key.IsEmpty())
	{
		pPageXObject->SetAtReference(key, pDocument, dwObjNum);
		CPDF_Dictionary* pNewOXbjectDic = pNewXObject->GetDict();
		pNewXORes = FX_NEW CPDF_Dictionary;
		pNewOXbjectDic->SetAt("Resources", pNewXORes);
		pNewOXbjectDic->SetAtName("Type", "XObject");
		pNewOXbjectDic->SetAtName("Subtype", "Form");
		pNewOXbjectDic->SetAtInteger("FormType", 1);
		pNewOXbjectDic->SetAtName("Name", "FRM");
		CPDF_Rect rcBBox = pPageDict->GetRect("ArtBox"); 
		pNewOXbjectDic->SetAtRect("BBox", rcBBox);
	}
	
	for (int i = 0; i < nStreams; i++)
	{
		CPDF_Dictionary* pAnnotDic = ObjectArray.GetAt(i);
		if (!pAnnotDic)continue;

		CPDF_Rect rcAnnot = pAnnotDic->GetRect("Rect");
		rcAnnot.Normalize();

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

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

			if (!sAnnotState.IsEmpty())
			{
				pAPStream = pAPDic->GetStream(sAnnotState);
			}
			else
			{
				FX_POSITION pos = pAPDic->GetStartPos();
				if (pos)
				{
					CFX_ByteString sKey;
					CPDF_Object* pFirstObj = pAPDic->GetNextElement(pos, sKey);
					if (pFirstObj)
					{
						if (pFirstObj->GetType() == PDFOBJ_REFERENCE)
							pFirstObj = pFirstObj->GetDirect();
						
						if (pFirstObj->GetType() != PDFOBJ_STREAM)
							continue;

						pAPStream = (CPDF_Stream*)pFirstObj;
					}
				}
			}
		}

		if (!pAPStream)continue;

		CPDF_Dictionary* pAPDic = pAPStream->GetDict();
		CFX_AffineMatrix matrix = pAPDic->GetMatrix("Matrix");

		CPDF_Rect rcStream;
		if (pAPDic->KeyExist("Rect"))
			rcStream = pAPDic->GetRect("Rect");
		else if (pAPDic->KeyExist("BBox"))
			rcStream = pAPDic->GetRect("BBox");

		if (rcStream.IsEmpty())continue;

		CPDF_Object* pObj = pAPStream;

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

		CPDF_Dictionary* pXObject = pNewXORes->GetDict("XObject");
		if (!pXObject)
		{
			pXObject = FX_NEW CPDF_Dictionary;
			pNewXORes->SetAt("XObject", pXObject);
		}

		CFX_ByteString sFormName;
		sFormName.Format("F%d", i);
		FX_DWORD dwObjNum = pDocument->AddIndirectObject(pObj);
		pXObject->SetAtReference(sFormName, pDocument, dwObjNum);

		CPDF_StreamAcc acc;
		acc.LoadAllData(pNewXObject);

		FX_LPCBYTE pData = acc.GetData();
		CFX_ByteString sStream(pData, acc.GetSize());
		CFX_ByteString sTemp;

		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_AffineMatrix 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((FX_LPCBYTE)sStream, sStream.GetLength(), FALSE, FALSE);
	}
	pPageDict->RemoveAt( "Annots" );

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

	return FLATTEN_SUCCESS;
}
예제 #25
0
void CPDFSDK_Annot::WriteAppearance(const CFX_ByteString& sAPType, const CPDF_Rect& rcBBox, 
								const CPDF_Matrix& matrix, const CFX_ByteString& sContents,
								const CFX_ByteString& sAPState)
{
	ASSERT(m_pAnnot != NULL);
	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
	
	CPDF_Dictionary* pAPDict = m_pAnnot->m_pAnnotDict->GetDict("AP");
	
	if (!pAPDict) 
	{
		pAPDict = FX_NEW CPDF_Dictionary;
		m_pAnnot->m_pAnnotDict->SetAt("AP", pAPDict);
	}
	
	CPDF_Stream* pStream = NULL;
	CPDF_Dictionary* pParentDict = NULL;
	
	if (sAPState.IsEmpty())
	{
		pParentDict = pAPDict;
		pStream = pAPDict->GetStream(sAPType);
	}
	else
	{
		CPDF_Dictionary* pAPTypeDict = pAPDict->GetDict(sAPType);
		if (!pAPTypeDict)
		{
			pAPTypeDict = FX_NEW CPDF_Dictionary;
			pAPDict->SetAt(sAPType, pAPTypeDict);
		}
		
		pParentDict = pAPTypeDict;
		pStream = pAPTypeDict->GetStream(sAPState);
	}
	
	if (!pStream) 
	{
		ASSERT(m_pPageView != NULL);
		CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
		ASSERT(pDoc != NULL);
		
		pStream = FX_NEW CPDF_Stream(NULL, 0, NULL);
		FX_INT32 objnum = pDoc->AddIndirectObject(pStream);
		//pAPDict->SetAtReference(sAPType, pDoc, objnum);
		ASSERT(pParentDict != NULL);
		pParentDict->SetAtReference(sAPType, pDoc, objnum);
	}
	
	CPDF_Dictionary * pStreamDict = pStream->GetDict();
	
	if (!pStreamDict)
	{
		pStreamDict = FX_NEW CPDF_Dictionary;
		pStreamDict->SetAtName("Type", "XObject");
		pStreamDict->SetAtName("Subtype", "Form");
		pStreamDict->SetAtInteger("FormType", 1);
		pStream->InitStream(NULL,0,pStreamDict);
	}
	
	if (pStreamDict)
	{
		pStreamDict->SetAtMatrix("Matrix",matrix);	
		pStreamDict->SetAtRect("BBox", rcBBox);		
	}
	
	pStream->SetData((FX_BYTE*)sContents.c_str(), sContents.GetLength(), FALSE, FALSE);
}