1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #ifndef CORE_INCLUDE_FPDFAPI_FPDF_OBJECTS_H_ 8 #define CORE_INCLUDE_FPDFAPI_FPDF_OBJECTS_H_ 9 10 #include "../fxcrt/fx_ext.h" 11 12 class CPDF_Array; 13 class CPDF_Boolean; 14 class CPDF_CryptoHandler; 15 class CPDF_Dictionary; 16 class CPDF_Document; 17 class CPDF_IndirectObjects; 18 class CPDF_Null; 19 class CPDF_Number; 20 class CPDF_Parser; 21 class CPDF_Reference; 22 class CPDF_Stream; 23 class CPDF_StreamAcc; 24 class CPDF_StreamFilter; 25 class CPDF_String; 26 class IFX_FileRead; 27 28 #define PDFOBJ_INVALID 0 29 #define PDFOBJ_BOOLEAN 1 30 #define PDFOBJ_NUMBER 2 31 #define PDFOBJ_STRING 3 32 #define PDFOBJ_NAME 4 33 #define PDFOBJ_ARRAY 5 34 #define PDFOBJ_DICTIONARY 6 35 #define PDFOBJ_STREAM 7 36 #define PDFOBJ_NULL 8 37 #define PDFOBJ_REFERENCE 9 38 39 typedef IFX_FileStream* (*FPDF_LPFCloneStreamCallback)(CPDF_Stream *pStream, FX_LPVOID pUserData); 40 class CPDF_Object 41 { 42 public: 43 GetType()44 int GetType() const 45 { 46 return m_Type; 47 } 48 GetObjNum()49 FX_DWORD GetObjNum() const 50 { 51 return m_ObjNum; 52 } 53 GetGenNum()54 FX_DWORD GetGenNum() const 55 { 56 return m_GenNum; 57 } 58 59 FX_BOOL IsIdentical(CPDF_Object* pObj) const; 60 61 CPDF_Object* Clone(FX_BOOL bDirect = FALSE) const; 62 63 CPDF_Object* CloneRef(CPDF_IndirectObjects* pObjs) const; 64 65 CPDF_Object* GetDirect() const; 66 67 void Release(); 68 69 CFX_ByteString GetString() const; 70 71 CFX_ByteStringC GetConstString() const; 72 73 CFX_WideString GetUnicodeText(CFX_CharMap* pCharMap = NULL) const; 74 FX_FLOAT GetNumber() const; 75 76 FX_FLOAT GetNumber16() const; 77 78 int GetInteger() const; 79 80 CPDF_Dictionary* GetDict() const; 81 82 CPDF_Array* GetArray() const; 83 84 void SetString(const CFX_ByteString& str); 85 86 void SetUnicodeText(FX_LPCWSTR pUnicodes, int len = -1); 87 88 int GetDirectType() const; 89 IsModified()90 FX_BOOL IsModified() const 91 { 92 return FALSE; 93 } 94 protected: CPDF_Object(FX_DWORD type)95 CPDF_Object(FX_DWORD type) : m_Type(type), m_ObjNum(0), m_GenNum(0) { } ~CPDF_Object()96 ~CPDF_Object() { } 97 void Destroy(); 98 99 static const int OBJECT_REF_MAX_DEPTH = 128; 100 static int s_nCurRefDepth; 101 FX_DWORD m_Type; 102 FX_DWORD m_ObjNum; 103 FX_DWORD m_GenNum; 104 105 friend class CPDF_IndirectObjects; 106 friend class CPDF_Parser; 107 friend class CPDF_SyntaxParser; 108 private: CPDF_Object(const CPDF_Object & src)109 CPDF_Object(const CPDF_Object& src) {} 110 CPDF_Object* CloneInternal(FX_BOOL bDirect, CFX_MapPtrToPtr* visited) const; 111 }; 112 class CPDF_Boolean : public CPDF_Object 113 { 114 public: 115 Create(FX_BOOL value)116 static CPDF_Boolean* Create(FX_BOOL value) 117 { 118 return new CPDF_Boolean(value); 119 } 120 CPDF_Boolean()121 CPDF_Boolean() : CPDF_Object(PDFOBJ_BOOLEAN), m_bValue(false) { } CPDF_Boolean(FX_BOOL value)122 CPDF_Boolean(FX_BOOL value) : CPDF_Object(PDFOBJ_BOOLEAN), m_bValue(value) { } 123 Identical(CPDF_Boolean * pOther)124 FX_BOOL Identical(CPDF_Boolean* pOther) const 125 { 126 return m_bValue == pOther->m_bValue; 127 } 128 protected: 129 130 FX_BOOL m_bValue; 131 friend class CPDF_Object; 132 }; 133 class CPDF_Number : public CPDF_Object 134 { 135 public: 136 Create(int value)137 static CPDF_Number* Create(int value) 138 { 139 return new CPDF_Number(value); 140 } 141 Create(FX_FLOAT value)142 static CPDF_Number* Create(FX_FLOAT value) 143 { 144 return new CPDF_Number(value); 145 } 146 Create(FX_BSTR str)147 static CPDF_Number* Create(FX_BSTR str) 148 { 149 return new CPDF_Number(str); 150 } 151 Create(FX_BOOL bInteger,void * pData)152 static CPDF_Number* Create(FX_BOOL bInteger, void* pData) 153 { 154 return new CPDF_Number(bInteger, pData); 155 } 156 CPDF_Number()157 CPDF_Number() : CPDF_Object(PDFOBJ_NUMBER), m_bInteger(false), m_Integer(0) { } 158 159 CPDF_Number(FX_BOOL bInteger, void* pData); 160 161 CPDF_Number(int value); 162 163 CPDF_Number(FX_FLOAT value); 164 165 CPDF_Number(FX_BSTR str); 166 167 FX_BOOL Identical(CPDF_Number* pOther) const; 168 169 CFX_ByteString GetString() const; 170 171 void SetString(FX_BSTR str); 172 IsInteger()173 FX_BOOL IsInteger() const 174 { 175 return m_bInteger; 176 } 177 GetInteger()178 int GetInteger() const 179 { 180 return m_bInteger ? m_Integer : (int)m_Float; 181 } 182 GetNumber()183 FX_FLOAT GetNumber() const 184 { 185 return m_bInteger ? (FX_FLOAT)m_Integer : m_Float; 186 } 187 188 void SetNumber(FX_FLOAT value); 189 GetNumber16()190 FX_FLOAT GetNumber16() const 191 { 192 return GetNumber(); 193 } 194 GetFloat()195 FX_FLOAT GetFloat() const 196 { 197 return m_bInteger ? (FX_FLOAT)m_Integer : m_Float; 198 } 199 protected: 200 201 FX_BOOL m_bInteger; 202 203 union { 204 205 int m_Integer; 206 207 FX_FLOAT m_Float; 208 }; 209 friend class CPDF_Object; 210 }; 211 class CPDF_String : public CPDF_Object 212 { 213 public: 214 215 static CPDF_String* Create(const CFX_ByteString& str, FX_BOOL bHex = FALSE) 216 { 217 return new CPDF_String(str, bHex); 218 } 219 Create(const CFX_WideString & str)220 static CPDF_String* Create(const CFX_WideString& str) 221 { 222 return new CPDF_String(str); 223 } 224 CPDF_String()225 CPDF_String() : CPDF_Object(PDFOBJ_STRING), m_bHex(FALSE) { } 226 227 CPDF_String(const CFX_ByteString& str, FX_BOOL bHex = FALSE) CPDF_Object(PDFOBJ_STRING)228 : CPDF_Object(PDFOBJ_STRING), m_String(str), m_bHex(bHex) { 229 } 230 231 CPDF_String(const CFX_WideString& str); 232 GetString()233 CFX_ByteString& GetString() 234 { 235 return m_String; 236 } 237 Identical(CPDF_String * pOther)238 FX_BOOL Identical(CPDF_String* pOther) const 239 { 240 return m_String == pOther->m_String; 241 } 242 IsHex()243 FX_BOOL IsHex() const 244 { 245 return m_bHex; 246 } 247 protected: 248 249 CFX_ByteString m_String; 250 251 FX_BOOL m_bHex; 252 friend class CPDF_Object; 253 }; 254 class CPDF_Name : public CPDF_Object 255 { 256 public: 257 Create(const CFX_ByteString & str)258 static CPDF_Name* Create(const CFX_ByteString& str) 259 { 260 return new CPDF_Name(str); 261 } 262 Create(FX_BSTR str)263 static CPDF_Name* Create(FX_BSTR str) 264 { 265 return new CPDF_Name(str); 266 } 267 Create(FX_LPCSTR str)268 static CPDF_Name* Create(FX_LPCSTR str) 269 { 270 return new CPDF_Name(str); 271 } 272 CPDF_Name(const CFX_ByteString & str)273 CPDF_Name(const CFX_ByteString& str) : CPDF_Object(PDFOBJ_NAME), m_Name(str) { } CPDF_Name(FX_BSTR str)274 CPDF_Name(FX_BSTR str) : CPDF_Object(PDFOBJ_NAME), m_Name(str) { } CPDF_Name(FX_LPCSTR str)275 CPDF_Name(FX_LPCSTR str) : CPDF_Object(PDFOBJ_NAME), m_Name(str) { } 276 GetString()277 CFX_ByteString& GetString() 278 { 279 return m_Name; 280 } 281 Identical(CPDF_Name * pOther)282 FX_BOOL Identical(CPDF_Name* pOther) const 283 { 284 return m_Name == pOther->m_Name; 285 } 286 protected: 287 288 CFX_ByteString m_Name; 289 friend class CPDF_Object; 290 }; 291 class CPDF_Array : public CPDF_Object 292 { 293 public: 294 Create()295 static CPDF_Array* Create() 296 { 297 return new CPDF_Array(); 298 } 299 CPDF_Array()300 CPDF_Array() : CPDF_Object(PDFOBJ_ARRAY) { } 301 GetCount()302 FX_DWORD GetCount() const 303 { 304 return m_Objects.GetSize(); 305 } 306 307 CPDF_Object* GetElement(FX_DWORD index) const; 308 309 CPDF_Object* GetElementValue(FX_DWORD index) const; 310 311 312 313 CFX_AffineMatrix GetMatrix(); 314 315 CFX_FloatRect GetRect(); 316 317 318 319 320 CFX_ByteString GetString(FX_DWORD index) const; 321 322 CFX_ByteStringC GetConstString(FX_DWORD index) const; 323 324 int GetInteger(FX_DWORD index) const; 325 326 FX_FLOAT GetNumber(FX_DWORD index) const; 327 328 CPDF_Dictionary* GetDict(FX_DWORD index) const; 329 330 CPDF_Stream* GetStream(FX_DWORD index) const; 331 332 CPDF_Array* GetArray(FX_DWORD index) const; 333 GetFloat(FX_DWORD index)334 FX_FLOAT GetFloat(FX_DWORD index) const 335 { 336 return GetNumber(index); 337 } 338 339 340 341 342 void SetAt(FX_DWORD index, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs = NULL); 343 344 345 void InsertAt(FX_DWORD index, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs = NULL); 346 347 void RemoveAt(FX_DWORD index); 348 349 350 void Add(CPDF_Object* pObj, CPDF_IndirectObjects* pObjs = NULL); 351 352 353 354 void AddNumber(FX_FLOAT f); 355 356 void AddInteger(int i); 357 358 void AddString(const CFX_ByteString& str); 359 360 void AddName(const CFX_ByteString& str); 361 362 void AddReference(CPDF_IndirectObjects* pDoc, FX_DWORD objnum); 363 AddReference(CPDF_IndirectObjects * pDoc,CPDF_Object * obj)364 void AddReference(CPDF_IndirectObjects* pDoc, CPDF_Object* obj) 365 { 366 AddReference(pDoc, obj->GetObjNum()); 367 } 368 369 GetNumber16(FX_DWORD index)370 FX_FLOAT GetNumber16(FX_DWORD index) const 371 { 372 return GetNumber(index); 373 } 374 AddNumber16(FX_FLOAT value)375 void AddNumber16(FX_FLOAT value) 376 { 377 AddNumber(value); 378 } 379 380 FX_BOOL Identical(CPDF_Array* pOther) const; 381 protected: 382 383 ~CPDF_Array(); 384 385 CFX_PtrArray m_Objects; 386 friend class CPDF_Object; 387 }; 388 class CPDF_Dictionary : public CPDF_Object 389 { 390 public: 391 Create()392 static CPDF_Dictionary* Create() 393 { 394 return new CPDF_Dictionary(); 395 } 396 CPDF_Dictionary()397 CPDF_Dictionary() : CPDF_Object(PDFOBJ_DICTIONARY) { } 398 399 CPDF_Object* GetElement(FX_BSTR key) const; 400 401 CPDF_Object* GetElementValue(FX_BSTR key) const; 402 403 404 405 406 407 CFX_ByteString GetString(FX_BSTR key) const; 408 409 CFX_ByteStringC GetConstString(FX_BSTR key) const; 410 411 CFX_ByteString GetString(FX_BSTR key, FX_BSTR default_str) const; 412 413 CFX_ByteStringC GetConstString(FX_BSTR key, FX_BSTR default_str) const; 414 415 CFX_WideString GetUnicodeText(FX_BSTR key, CFX_CharMap* pCharMap = NULL) const; 416 417 int GetInteger(FX_BSTR key) const; 418 419 int GetInteger(FX_BSTR key, int default_int) const; 420 421 FX_BOOL GetBoolean(FX_BSTR key, FX_BOOL bDefault = FALSE) const; 422 423 FX_FLOAT GetNumber(FX_BSTR key) const; 424 425 CPDF_Dictionary* GetDict(FX_BSTR key) const; 426 427 CPDF_Stream* GetStream(FX_BSTR key) const; 428 429 CPDF_Array* GetArray(FX_BSTR key) const; 430 431 CFX_FloatRect GetRect(FX_BSTR key) const; 432 433 CFX_AffineMatrix GetMatrix(FX_BSTR key) const; 434 GetFloat(FX_BSTR key)435 FX_FLOAT GetFloat(FX_BSTR key) const 436 { 437 return GetNumber(key); 438 } 439 440 441 FX_BOOL KeyExist(FX_BSTR key) const; 442 443 FX_POSITION GetStartPos() const; 444 445 CPDF_Object* GetNextElement(FX_POSITION& pos, CFX_ByteString& key) const; 446 447 void SetAt(FX_BSTR key, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs = NULL); 448 449 450 451 void SetAtName(FX_BSTR key, const CFX_ByteString& name); 452 453 454 void SetAtString(FX_BSTR key, const CFX_ByteString& string); 455 456 457 void SetAtInteger(FX_BSTR key, int i); 458 459 460 void SetAtNumber(FX_BSTR key, FX_FLOAT f); 461 462 void SetAtReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, FX_DWORD objnum); 463 SetAtReference(FX_BSTR key,CPDF_IndirectObjects * pDoc,CPDF_Object * obj)464 void SetAtReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, CPDF_Object* obj) 465 { 466 SetAtReference(key, pDoc, obj->GetObjNum()); 467 } 468 469 void AddReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, FX_DWORD objnum); 470 AddReference(FX_BSTR key,CPDF_IndirectObjects * pDoc,CPDF_Object * obj)471 void AddReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, CPDF_Object* obj) 472 { 473 AddReference(key, pDoc, obj->GetObjNum()); 474 } 475 476 void SetAtRect(FX_BSTR key, const CFX_FloatRect& rect); 477 478 void SetAtMatrix(FX_BSTR key, const CFX_AffineMatrix& matrix); 479 480 void SetAtBoolean(FX_BSTR key, FX_BOOL bValue); 481 482 483 484 void RemoveAt(FX_BSTR key); 485 486 487 void ReplaceKey(FX_BSTR oldkey, FX_BSTR newkey); 488 489 FX_BOOL Identical(CPDF_Dictionary* pDict) const; 490 GetCount()491 int GetCount() const 492 { 493 return m_Map.GetCount(); 494 } 495 496 void AddValue(FX_BSTR key, CPDF_Object* pObj); 497 protected: 498 499 ~CPDF_Dictionary(); 500 501 CFX_CMapByteStringToPtr m_Map; 502 503 friend class CPDF_Object; 504 }; 505 class CPDF_Stream : public CPDF_Object 506 { 507 public: 508 Create(FX_LPBYTE pData,FX_DWORD size,CPDF_Dictionary * pDict)509 static CPDF_Stream* Create(FX_LPBYTE pData, FX_DWORD size, CPDF_Dictionary* pDict) 510 { 511 return new CPDF_Stream(pData, size, pDict); 512 } 513 514 CPDF_Stream(FX_LPBYTE pData, FX_DWORD size, CPDF_Dictionary* pDict); 515 GetDict()516 CPDF_Dictionary* GetDict() const 517 { 518 return m_pDict; 519 } 520 521 void SetData(FX_LPCBYTE pData, FX_DWORD size, FX_BOOL bCompressed, FX_BOOL bKeepBuf); 522 523 void InitStream(FX_BYTE* pData, FX_DWORD size, CPDF_Dictionary* pDict); 524 525 void InitStream(IFX_FileRead *pFile, CPDF_Dictionary* pDict); 526 527 FX_BOOL Identical(CPDF_Stream* pOther) const; 528 529 CPDF_StreamFilter* GetStreamFilter(FX_BOOL bRaw = FALSE) const; 530 531 532 GetRawSize()533 FX_DWORD GetRawSize() const 534 { 535 return m_dwSize; 536 } 537 538 FX_BOOL ReadRawData(FX_FILESIZE start_pos, FX_LPBYTE pBuf, FX_DWORD buf_size) const; 539 540 IsMemoryBased()541 FX_BOOL IsMemoryBased() const 542 { 543 return m_GenNum == (FX_DWORD) - 1; 544 } 545 546 CPDF_Stream* Clone(FX_BOOL bDirect, FPDF_LPFCloneStreamCallback lpfCallback, FX_LPVOID pUserData) const; 547 protected: 548 549 ~CPDF_Stream(); 550 551 CPDF_Dictionary* m_pDict; 552 553 FX_DWORD m_dwSize; 554 555 FX_DWORD m_GenNum; 556 557 union { 558 559 FX_LPBYTE m_pDataBuf; 560 561 IFX_FileRead* m_pFile; 562 }; 563 564 FX_FILESIZE m_FileOffset; 565 566 CPDF_CryptoHandler* m_pCryptoHandler; 567 568 void InitStream(CPDF_Dictionary* pDict); 569 friend class CPDF_Object; 570 friend class CPDF_StreamAcc; 571 friend class CPDF_AttachmentAcc; 572 }; 573 class CPDF_StreamAcc 574 { 575 public: 576 577 CPDF_StreamAcc(); 578 579 ~CPDF_StreamAcc(); 580 581 void LoadAllData(const CPDF_Stream* pStream, FX_BOOL bRawAccess = FALSE, 582 FX_DWORD estimated_size = 0, FX_BOOL bImageAcc = FALSE); 583 GetStream()584 const CPDF_Stream* GetStream() const 585 { 586 return m_pStream; 587 } 588 GetDict()589 CPDF_Dictionary* GetDict() const 590 { 591 return m_pStream? m_pStream->GetDict() : NULL; 592 } 593 594 FX_LPCBYTE GetData() const; 595 596 FX_DWORD GetSize() const; 597 598 FX_LPBYTE DetachData(); 599 GetImageDecoder()600 const CFX_ByteString& GetImageDecoder() 601 { 602 return m_ImageDecoder; 603 } 604 GetImageParam()605 const CPDF_Dictionary* GetImageParam() 606 { 607 return m_pImageParam; 608 } 609 protected: 610 611 FX_LPBYTE m_pData; 612 613 FX_DWORD m_dwSize; 614 615 FX_BOOL m_bNewBuf; 616 617 CFX_ByteString m_ImageDecoder; 618 619 CPDF_Dictionary* m_pImageParam; 620 621 const CPDF_Stream* m_pStream; 622 623 FX_LPBYTE m_pSrcData; 624 }; 625 CFX_DataFilter* FPDF_CreateFilter(FX_BSTR name, const CPDF_Dictionary* pParam, int width = 0, int height = 0); 626 #define FPDF_FILTER_BUFFER_SIZE 20480 627 class CPDF_StreamFilter 628 { 629 public: 630 631 ~CPDF_StreamFilter(); 632 633 FX_DWORD ReadBlock(FX_LPBYTE buffer, FX_DWORD size); 634 GetSrcPos()635 FX_DWORD GetSrcPos() 636 { 637 return m_SrcOffset; 638 } 639 GetStream()640 const CPDF_Stream* GetStream() 641 { 642 return m_pStream; 643 } 644 protected: 645 CPDF_StreamFilter()646 CPDF_StreamFilter() {} 647 648 FX_DWORD ReadLeftOver(FX_LPBYTE buffer, FX_DWORD buf_size); 649 650 const CPDF_Stream* m_pStream; 651 652 CFX_DataFilter* m_pFilter; 653 654 CFX_BinaryBuf* m_pBuffer; 655 656 FX_DWORD m_BufOffset; 657 658 FX_DWORD m_SrcOffset; 659 660 FX_BYTE m_SrcBuffer[FPDF_FILTER_BUFFER_SIZE]; 661 friend class CPDF_Stream; 662 }; 663 class CPDF_Null : public CPDF_Object 664 { 665 public: 666 Create()667 static CPDF_Null* Create() 668 { 669 return new CPDF_Null(); 670 } 671 CPDF_Null()672 CPDF_Null() : CPDF_Object(PDFOBJ_NULL) { } 673 }; 674 class CPDF_Reference : public CPDF_Object 675 { 676 public: 677 Create(CPDF_IndirectObjects * pDoc,int objnum)678 static CPDF_Reference* Create(CPDF_IndirectObjects* pDoc, int objnum) 679 { 680 return new CPDF_Reference(pDoc, objnum); 681 } 682 CPDF_Reference(CPDF_IndirectObjects * pDoc,int objnum)683 CPDF_Reference(CPDF_IndirectObjects* pDoc, int objnum) 684 : CPDF_Object(PDFOBJ_REFERENCE), m_pObjList(pDoc), m_RefObjNum(objnum) { 685 } 686 GetObjList()687 CPDF_IndirectObjects* GetObjList() const 688 { 689 return m_pObjList; 690 } 691 GetRefObjNum()692 FX_DWORD GetRefObjNum() const 693 { 694 return m_RefObjNum; 695 } 696 697 void SetRef(CPDF_IndirectObjects* pDoc, FX_DWORD objnum); 698 Identical(CPDF_Reference * pOther)699 FX_BOOL Identical(CPDF_Reference* pOther) const 700 { 701 return m_RefObjNum == pOther->m_RefObjNum; 702 } 703 protected: 704 705 CPDF_IndirectObjects* m_pObjList; 706 707 FX_DWORD m_RefObjNum; 708 friend class CPDF_Object; 709 }; 710 class CPDF_IndirectObjects 711 { 712 public: 713 714 CPDF_IndirectObjects(CPDF_Parser* pParser); 715 716 ~CPDF_IndirectObjects(); 717 718 CPDF_Object* GetIndirectObject(FX_DWORD objnum, struct PARSE_CONTEXT* pContext = NULL); 719 720 int GetIndirectType(FX_DWORD objnum); 721 722 FX_DWORD AddIndirectObject(CPDF_Object* pObj); 723 724 void ReleaseIndirectObject(FX_DWORD objnum); 725 726 void InsertIndirectObject(FX_DWORD objnum, CPDF_Object* pObj); 727 728 FX_DWORD GetLastObjNum() const; 729 GetStartPosition()730 FX_POSITION GetStartPosition() const 731 { 732 return m_IndirectObjs.GetStartPosition(); 733 } 734 GetNextAssoc(FX_POSITION & rPos,FX_DWORD & objnum,CPDF_Object * & pObject)735 void GetNextAssoc(FX_POSITION& rPos, FX_DWORD& objnum, CPDF_Object*& pObject) const 736 { 737 m_IndirectObjs.GetNextAssoc(rPos, (void*&)objnum, (void*&)pObject); 738 } 739 protected: 740 741 CFX_MapPtrToPtr m_IndirectObjs; 742 743 CPDF_Parser* m_pParser; 744 745 FX_DWORD m_LastObjNum; 746 }; 747 748 #endif // CORE_INCLUDE_FPDFAPI_FPDF_OBJECTS_H_ 749