File: character_composer.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (158 lines) | stat: -rw-r--r-- 4,981 bytes parent folder | download | duplicates (3)
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_BASE_IME_CHARACTER_COMPOSER_H_
#define UI_BASE_IME_CHARACTER_COMPOSER_H_

#include <stddef.h>
#include <stdint.h>

#include <vector>

#include "base/component_export.h"
#include "base/memory/raw_ptr_exclusion.h"
#include "base/memory/raw_ref.h"
#include "base/strings/string_util.h"
#include "ui/events/keycodes/dom/dom_key.h"

namespace ui {
class KeyEvent;

// A class to recognize compose and dead key sequence.
// Outputs composed character.
class COMPONENT_EXPORT(UI_BASE_IME_TYPES) CharacterComposer {
 public:
  using ComposeBuffer = std::vector<DomKey>;

  // The U+00B7 "middle dot" character is also used by GTK to represent the
  // compose key in preedit strings.
  static constexpr char16_t kPreeditStringComposeKeySymbol = 0x00B7;

  // Decides in which modes the preedit string is enabled. If disabled for a
  // mode, it is always empty in that mode.
  enum class PreeditStringMode {
    // Enable in both hex and sequence mode.
    kAlwaysEnabled,
    // Enable in hex mode, disable in sequence mode.
    kHexModeOnly,
  };

  // Disable the preedit string in sequence mode by default.
  explicit CharacterComposer(
      PreeditStringMode mode = PreeditStringMode::kHexModeOnly);

  CharacterComposer(const CharacterComposer&) = delete;
  CharacterComposer& operator=(const CharacterComposer&) = delete;

  ~CharacterComposer();

  void Reset();

  // Filters keypress.
  // Returns true if the keypress is recognized as a part of composition
  // sequence.
  // Fabricated events which don't have the native event, are not supported.
  bool FilterKeyPress(const ui::KeyEvent& event);

  // Returns a string consisting of composed character.
  // Empty string is returned when there is no composition result.
  const std::u16string& composed_character() const {
    return composed_character_;
  }

  // Returns the preedit string.
  const std::u16string& preedit_string() const { return preedit_string_; }

 private:
  // An enum to describe composition mode.
  enum CompositionMode {
    // This is the initial state.
    // Composite a character with dead-keys and compose-key.
    KEY_SEQUENCE_MODE,
    // Composite a character with a hexadecimal unicode sequence.
    HEX_MODE,
  };

  // Filters keypress in key sequence mode.
  bool FilterKeyPressSequenceMode(const ui::KeyEvent& event);

  // Updates preedit string in key sequence mode.
  void UpdatePreeditStringSequenceMode();

  // Filters keypress in hexadecimal mode.
  bool FilterKeyPressHexMode(const ui::KeyEvent& event);

  // Commit a character composed from hexadecimal uncode sequence
  void CommitHex();

  // Updates preedit string in hexadecimal mode.
  void UpdatePreeditStringHexMode();

  // Remembers keypresses previously filtered.
  std::vector<DomKey> compose_buffer_;

  // Records hexadecimal digits previously filtered.
  std::vector<unsigned int> hex_buffer_;

  // A string representing the composed character.
  std::u16string composed_character_;

  // Preedit string.
  std::u16string preedit_string_;

  // Composition mode which this instance is in.
  CompositionMode composition_mode_ = KEY_SEQUENCE_MODE;

  const PreeditStringMode preedit_string_mode_;
};

// Abstract class for determining whether a ComposeBuffer forms a valid
// character composition sequence.
class ComposeChecker {
 public:
  enum class CheckSequenceResult {
    // The sequence is not a composition sequence or the prefix of any
    // composition sequence.
    NO_MATCH,
    // The sequence is a prefix of one or more composition sequences.
    PREFIX_MATCH,
    // The sequence matches a composition sequence.
    FULL_MATCH
  };
  ComposeChecker() = default;

  ComposeChecker(const ComposeChecker&) = delete;
  ComposeChecker& operator=(const ComposeChecker&) = delete;

  virtual ~ComposeChecker() {}
  virtual CheckSequenceResult CheckSequence(
      const ui::CharacterComposer::ComposeBuffer& sequence,
      uint32_t* composed_character) const = 0;
};

// Implementation of |ComposeChecker| using a compact generated tree.
class TreeComposeChecker : public ComposeChecker {
 public:
  struct CompositionData {
    size_t maximum_sequence_length;
    int tree_entries;
    // This field is not a raw_ptr<> because it only ever points at statically-
    // allocated memory which is never freed (kCompositionsTree), and hence
    // can never dangle.
    RAW_PTR_EXCLUSION const uint16_t* tree;
  };

  explicit TreeComposeChecker(const CompositionData& data) : data_(data) {}
  CheckSequenceResult CheckSequence(
      const ui::CharacterComposer::ComposeBuffer& sequence,
      uint32_t* composed_character) const override;

 private:
  bool Find(uint16_t index, uint16_t size, uint16_t key, uint16_t* value) const;
  const raw_ref<const CompositionData> data_;
};

}  // namespace ui

#endif  // UI_BASE_IME_CHARACTER_COMPOSER_H_