| // Copyright 2016 PDFium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| |
| #ifndef CORE_FPDFTEXT_CPDF_TEXTPAGE_H_ |
| #define CORE_FPDFTEXT_CPDF_TEXTPAGE_H_ |
| |
| #include <deque> |
| #include <functional> |
| #include <vector> |
| |
| #include "core/fpdfapi/page/cpdf_pageobjectholder.h" |
| #include "core/fxcrt/cfx_widetextbuf.h" |
| #include "core/fxcrt/fx_coordinates.h" |
| #include "core/fxcrt/fx_memory_wrappers.h" |
| #include "core/fxcrt/unowned_ptr.h" |
| #include "core/fxcrt/widestring.h" |
| #include "third_party/abseil-cpp/absl/types/optional.h" |
| |
| class CPDF_FormObject; |
| class CPDF_Page; |
| class CPDF_TextObject; |
| |
| class CPDF_TextPage { |
| public: |
| enum class CharType : uint8_t { |
| kNormal, |
| kGenerated, |
| kNotUnicode, |
| kHyphen, |
| kPiece, |
| }; |
| |
| class CharInfo { |
| public: |
| CharInfo(); |
| CharInfo(const CharInfo&); |
| ~CharInfo(); |
| |
| int m_Index = 0; |
| uint32_t m_CharCode = 0; |
| wchar_t m_Unicode = 0; |
| CharType m_CharType = CharType::kNormal; |
| CFX_PointF m_Origin; |
| CFX_FloatRect m_CharBox; |
| UnownedPtr<const CPDF_TextObject> m_pTextObj; |
| CFX_Matrix m_Matrix; |
| }; |
| |
| CPDF_TextPage(const CPDF_Page* pPage, bool rtl); |
| ~CPDF_TextPage(); |
| |
| int CharIndexFromTextIndex(int text_index) const; |
| int TextIndexFromCharIndex(int char_index) const; |
| size_t size() const { return m_CharList.size(); } |
| int CountChars() const; |
| |
| // These methods CHECK() to make sure |index| is within bounds. |
| const CharInfo& GetCharInfo(size_t index) const; |
| float GetCharFontSize(size_t index) const; |
| CFX_FloatRect GetCharLooseBounds(size_t index) const; |
| |
| std::vector<CFX_FloatRect> GetRectArray(int start, int count) const; |
| int GetIndexAtPos(const CFX_PointF& point, const CFX_SizeF& tolerance) const; |
| WideString GetTextByRect(const CFX_FloatRect& rect) const; |
| WideString GetTextByObject(const CPDF_TextObject* pTextObj) const; |
| |
| // Returns string with the text from |m_TextBuf| that are covered by the input |
| // range. |start| and |count| are in terms of the |m_CharIndices|, so the |
| // range will be converted into appropriate indices. |
| WideString GetPageText(int start, int count) const; |
| WideString GetAllPageText() const { return GetPageText(0, CountChars()); } |
| |
| int CountRects(int start, int nCount); |
| bool GetRect(int rectIndex, CFX_FloatRect* pRect) const; |
| |
| private: |
| enum class TextOrientation { |
| kUnknown, |
| kHorizontal, |
| kVertical, |
| }; |
| |
| enum class GenerateCharacter { |
| kNone, |
| kSpace, |
| kLineBreak, |
| kHyphen, |
| }; |
| |
| enum class MarkedContentState { kPass = 0, kDone, kDelay }; |
| |
| struct TransformedTextObject { |
| TransformedTextObject(); |
| TransformedTextObject(const TransformedTextObject& that); |
| ~TransformedTextObject(); |
| |
| UnownedPtr<const CPDF_TextObject> m_pTextObj; |
| CFX_Matrix m_formMatrix; |
| }; |
| |
| void Init(); |
| bool IsHyphen(wchar_t curChar) const; |
| void ProcessObject(); |
| void ProcessFormObject(CPDF_FormObject* pFormObj, |
| const CFX_Matrix& formMatrix); |
| void ProcessTextObject(const TransformedTextObject& obj); |
| void ProcessTextObject(CPDF_TextObject* pTextObj, |
| const CFX_Matrix& formMatrix, |
| const CPDF_PageObjectHolder* pObjList, |
| CPDF_PageObjectHolder::const_iterator ObjPos); |
| GenerateCharacter ProcessInsertObject(const CPDF_TextObject* pObj, |
| const CFX_Matrix& formMatrix); |
| const CharInfo* GetPrevCharInfo() const; |
| absl::optional<CharInfo> GenerateCharInfo(wchar_t unicode); |
| bool IsSameAsPreTextObject(CPDF_TextObject* pTextObj, |
| const CPDF_PageObjectHolder* pObjList, |
| CPDF_PageObjectHolder::const_iterator iter) const; |
| bool IsSameTextObject(CPDF_TextObject* pTextObj1, |
| CPDF_TextObject* pTextObj2) const; |
| void CloseTempLine(); |
| MarkedContentState PreMarkedContent(const CPDF_TextObject* pTextObj); |
| void ProcessMarkedContent(const TransformedTextObject& obj); |
| void FindPreviousTextObject(); |
| void AddCharInfoByLRDirection(wchar_t wChar, const CharInfo& info); |
| void AddCharInfoByRLDirection(wchar_t wChar, const CharInfo& info); |
| TextOrientation GetTextObjectWritingMode( |
| const CPDF_TextObject* pTextObj) const; |
| TextOrientation FindTextlineFlowOrientation() const; |
| void AppendGeneratedCharacter(wchar_t unicode, const CFX_Matrix& formMatrix); |
| void SwapTempTextBuf(size_t iCharListStartAppend, size_t iBufStartAppend); |
| WideString GetTextByPredicate( |
| const std::function<bool(const CharInfo&)>& predicate) const; |
| |
| UnownedPtr<const CPDF_Page> const m_pPage; |
| std::vector<uint16_t, FxAllocAllocator<uint16_t>> m_CharIndices; |
| std::deque<CharInfo> m_CharList; |
| std::deque<CharInfo> m_TempCharList; |
| CFX_WideTextBuf m_TextBuf; |
| CFX_WideTextBuf m_TempTextBuf; |
| UnownedPtr<const CPDF_TextObject> m_pPrevTextObj; |
| CFX_Matrix m_PrevMatrix; |
| const bool m_rtl; |
| const CFX_Matrix m_DisplayMatrix; |
| std::vector<CFX_FloatRect> m_SelRects; |
| std::vector<TransformedTextObject> mTextObjects; |
| TextOrientation m_TextlineDir = TextOrientation::kUnknown; |
| CFX_FloatRect m_CurlineRect; |
| }; |
| |
| #endif // CORE_FPDFTEXT_CPDF_TEXTPAGE_H_ |