xref: /aosp_15_r20/external/pdfium/core/fxcrt/fx_bidi.h (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2014 The PDFium Authors
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 <stdint.h>
11 
12 #include <vector>
13 
14 #include "core/fxcrt/widestring.h"
15 
16 // Processes characters and group them into segments based on text direction.
17 class CFX_BidiChar {
18  public:
19   enum class Direction { kNeutral, kLeft, kRight, kLeftWeak };
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, left-weak, 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(wchar_t 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   const 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 WideString& str);
54   ~CFX_BidiString();
55 
56   // Overall direction is always LEFT or RIGHT, never NEUTRAL.
57   CFX_BidiChar::Direction OverallDirection() const;
58 
59   // Force the overall direction to be R2L regardless of what was detected.
60   void SetOverallDirectionRight();
61 
begin()62   const_iterator begin() const { return m_Order.begin(); }
end()63   const_iterator end() const { return m_Order.end(); }
64 
65  private:
66   const WideString& m_Str;
67   std::vector<CFX_BidiChar::Segment> m_Order;
68   CFX_BidiChar::Direction m_eOverallDirection = CFX_BidiChar::Direction::kLeft;
69 };
70 
71 #endif  // CORE_FXCRT_FX_BIDI_H_
72