• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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