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