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