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_FXCRT_FX_BIDI_H_ 8 #define CORE_FXCRT_FX_BIDI_H_ 9 10 #include <memory> 11 #include <vector> 12 13 #include "core/fxcrt/fx_string.h" 14 #include "core/fxcrt/fx_system.h" 15 16 #ifdef PDF_ENABLE_XFA 17 #include "core/fxcrt/cfx_char.h" 18 #endif // PDF_ENABLE_XFA 19 20 // Processes characters and group them into segments based on text direction. 21 class CFX_BidiChar { 22 public: 23 enum Direction { NEUTRAL, LEFT, RIGHT }; 24 struct Segment { 25 int32_t start; // Start position. 26 int32_t count; // Character count. 27 Direction direction; // Segment direction. 28 }; 29 30 CFX_BidiChar(); 31 32 // Append a character and classify it as left, right, or neutral. 33 // Returns true if the character has a different direction than the 34 // existing direction to indicate there is a segment to process. 35 bool AppendChar(wchar_t wch); 36 37 // Call this after the last character has been appended. AppendChar() 38 // must not be called after this. 39 // Returns true if there is still a segment to process. 40 bool EndChar(); 41 42 // Call after a change in direction is indicated by the above to get 43 // information about the segment to process. GetSegmentInfo()44 Segment GetSegmentInfo() const { return m_LastSegment; } 45 46 private: 47 void StartNewSegment(CFX_BidiChar::Direction direction); 48 49 Segment m_CurrentSegment; 50 Segment m_LastSegment; 51 }; 52 53 class CFX_BidiString { 54 public: 55 using const_iterator = std::vector<CFX_BidiChar::Segment>::const_iterator; 56 57 explicit CFX_BidiString(const WideString& str); 58 ~CFX_BidiString(); 59 60 // Overall direction is always LEFT or RIGHT, never NEUTRAL. OverallDirection()61 CFX_BidiChar::Direction OverallDirection() const { 62 return m_eOverallDirection; 63 } 64 65 // Force the overall direction to be R2L regardless of what was detected. 66 void SetOverallDirectionRight(); 67 CharAt(size_t x)68 wchar_t CharAt(size_t x) const { return m_Str[x]; } begin()69 const_iterator begin() const { return m_Order.begin(); } end()70 const_iterator end() const { return m_Order.end(); } 71 72 private: 73 const WideString m_Str; 74 std::unique_ptr<CFX_BidiChar> m_pBidiChar; 75 std::vector<CFX_BidiChar::Segment> m_Order; 76 CFX_BidiChar::Direction m_eOverallDirection; 77 }; 78 79 #if PDF_ENABLE_XFA 80 void FX_BidiLine(std::vector<CFX_Char>* chars, size_t iCount); 81 #endif // PDF_ENABLE_XFA 82 83 #endif // CORE_FXCRT_FX_BIDI_H_ 84