1 // Copyright (c) 2016-2020 Thomas Fussell
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 // THE SOFTWARE
20 //
21 // @license: http://www.opensource.org/licenses/mit-license.php
22 // @author: see AUTHORS file
23 
24 #pragma once
25 
26 #include <string>
27 #include <vector>
28 
29 #include <xlnt/xlnt_config.hpp>
30 #include <xlnt/cell/phonetic_run.hpp>
31 #include <xlnt/cell/rich_text_run.hpp>
32 #include <xlnt/worksheet/phonetic_pr.hpp>
33 
34 namespace xlnt {
35 
36 /// <summary>
37 /// Encapsulates zero or more formatted text runs where a text run
38 /// is a string of text with the same defined formatting.
39 /// </summary>
40 class XLNT_API rich_text
41 {
42 public:
43     /// <summary>
44     /// Constructs an empty rich text object with no font and empty text.
45     /// </summary>
46     rich_text() = default;
47 
48     /// <summary>
49     /// Constructs a rich text object with the given text and no font.
50     /// </summary>
51     rich_text(const std::string &plain_text);
52 
53     /// <summary>
54     /// Constructs a rich text object from other
55     /// </summary>
56     rich_text(const rich_text &other);
57 
58     /// <summary>
59     /// Constructs a rich text object with the given text and font.
60     /// </summary>
61     rich_text(const std::string &plain_text, const class font &text_font);
62 
63     /// <summary>
64     /// Copy constructor.
65     /// </summary>
66     rich_text(const rich_text_run &single_run);
67 
68     /// <summary>
69     /// Removes all text runs from this text.
70     /// </summary>
71     void clear();
72 
73     /// <summary>
74     /// Clears any runs in this text and adds a single run with default formatting and
75     /// the given string as its textual content.
76     /// </summary>
77     void plain_text(const std::string &s, bool preserve_space);
78 
79     /// <summary>
80     /// Combines the textual content of each text run in order and returns the result.
81     /// </summary>
82     std::string plain_text() const;
83 
84     /// <summary>
85     /// Returns a copy of the individual runs that comprise this text.
86     /// </summary>
87     std::vector<rich_text_run> runs() const;
88 
89     /// <summary>
90     /// Sets the runs of this text all at once.
91     /// </summary>
92     void runs(const std::vector<rich_text_run> &new_runs);
93 
94     /// <summary>
95     /// Adds a new run to the end of the set of runs.
96     /// </summary>
97     void add_run(const rich_text_run &t);
98 
99     /// <summary>
100     /// Returns a copy of the individual runs that comprise this text.
101     /// </summary>
102     std::vector<phonetic_run> phonetic_runs() const;
103 
104     /// <summary>
105     /// Sets the runs of this text all at once.
106     /// </summary>
107     void phonetic_runs(const std::vector<phonetic_run> &new_phonetic_runs);
108 
109     /// <summary>
110     /// Adds a new run to the end of the set of runs.
111     /// </summary>
112     void add_phonetic_run(const phonetic_run &t);
113 
114     /// <summary>
115     /// Returns true if this text has phonetic properties
116     /// </summary>
117     bool has_phonetic_properties() const;
118 
119     /// <summary>
120     /// Returns the phonetic properties of this text.
121     /// </summary>
122     const phonetic_pr &phonetic_properties() const;
123 
124     /// <summary>
125     /// Sets the phonetic properties of this text to phonetic_props
126     /// </summary>
127     void phonetic_properties(const phonetic_pr &phonetic_props);
128 
129     /// <summary>
130     /// Copies rich text object from other
131     /// </summary>
132     rich_text &operator=(const rich_text &rhs);
133 
134     /// <summary>
135     /// Returns true if the runs that make up this text are identical to those in rhs.
136     /// </summary>
137     bool operator==(const rich_text &rhs) const;
138 
139     /// <summary>
140     /// Returns true if the runs that make up this text are identical to those in rhs.
141     /// </summary>
142     bool operator!=(const rich_text &rhs) const;
143 
144     /// <summary>
145     /// Returns true if this text has a single unformatted run with text equal to rhs.
146     /// </summary>
147     bool operator==(const std::string &rhs) const;
148 
149     /// <summary>
150     /// Returns true if this text has a single unformatted run with text equal to rhs.
151     /// </summary>
152     bool operator!=(const std::string &rhs) const;
153 
154 private:
155     /// <summary>
156     /// The runs that make up this rich text.
157     /// </summary>
158     std::vector<rich_text_run> runs_;
159     std::vector<phonetic_run> phonetic_runs_;
160     optional<phonetic_pr> phonetic_properties_;
161 };
162 
163 class XLNT_API rich_text_hash
164 {
165 public:
operator ()(const rich_text & k) const166     std::size_t operator()(const rich_text &k) const
167     {
168         std::size_t res = 0;
169 
170         for (auto r : k.runs())
171         {
172             res ^= std::hash<std::string>()(r.first);
173         }
174 
175         return res;
176     }
177 };
178 
179 } // namespace xlnt
180