summaryrefslogtreecommitdiff
path: root/core/fxcrt/fx_bidi.h
blob: f64fc67e2ef536adf7a9c3b4a1b7937104cdee11 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#ifndef CORE_FXCRT_FX_BIDI_H_
#define CORE_FXCRT_FX_BIDI_H_

#include <vector>

#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/fx_system.h"

#ifdef PDF_ENABLE_XFA
#include "core/fxcrt/cfx_char.h"
#endif  // PDF_ENABLE_XFA

// Processes characters and group them into segments based on text direction.
class CFX_BidiChar {
 public:
  enum Direction { NEUTRAL, LEFT, RIGHT };
  struct Segment {
    int32_t start;        // Start position.
    int32_t count;        // Character count.
    Direction direction;  // Segment direction.
  };

  CFX_BidiChar();

  // Append a character and classify it as left, right, or neutral.
  // Returns true if the character has a different direction than the
  // existing direction to indicate there is a segment to process.
  bool AppendChar(wchar_t wch);

  // Call this after the last character has been appended. AppendChar()
  // must not be called after this.
  // Returns true if there is still a segment to process.
  bool EndChar();

  // Call after a change in direction is indicated by the above to get
  // information about the segment to process.
  const Segment& GetSegmentInfo() const { return m_LastSegment; }

 private:
  void StartNewSegment(CFX_BidiChar::Direction direction);

  Segment m_CurrentSegment;
  Segment m_LastSegment;
};

class CFX_BidiString {
 public:
  using const_iterator = std::vector<CFX_BidiChar::Segment>::const_iterator;

  explicit CFX_BidiString(const WideString& str);
  ~CFX_BidiString();

  // Overall direction is always LEFT or RIGHT, never NEUTRAL.
  CFX_BidiChar::Direction OverallDirection() const;

  // Force the overall direction to be R2L regardless of what was detected.
  void SetOverallDirectionRight();

  const_iterator begin() const { return m_Order.begin(); }
  const_iterator end() const { return m_Order.end(); }

 private:
  const WideString& m_Str;
  std::vector<CFX_BidiChar::Segment> m_Order;
  CFX_BidiChar::Direction m_eOverallDirection = CFX_BidiChar::LEFT;
};

#ifdef PDF_ENABLE_XFA
void FX_BidiLine(std::vector<CFX_Char>* chars, size_t iCount);
#endif  // PDF_ENABLE_XFA

#endif  // CORE_FXCRT_FX_BIDI_H_