1 /*
2  * Copyright (c) 2017 Rafal Lalik rafallalik@gmail.com
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use,
8  * copy, modify, merge, publish, distribute, sublicense, and/or sell
9  * copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following
11  * conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23  * OTHER DEALINGS IN THE SOFTWARE.
24  */
25 
26 #ifndef TYPEWRITER_H
27 #define TYPEWRITER_H
28 
29 #include <string>
30 #include <vector>
31 #include <random>
32 
33 #include <QDomElement>
34 
35 using namespace std;
36 
37 struct Frame
38 {
39     Frame(uint frame, uint real_frame);
40 
41     uint frame;
42     uint real_frame;
43     std::string s;
44     int bypass;
45 
46     void print();
47 };
48 
49 class TypeWriter
50 {
51 public:
52     TypeWriter();
53     virtual ~TypeWriter() = default;
54 
setFrameRate(uint fr)55     void setFrameRate(uint fr) { frame_rate = fr; }
getFrameRate()56     uint getFrameRate() const { return frame_rate; }
57 
setFrameStep(uint fs)58     void setFrameStep(uint fs) { frame_step = fs; }
getFrameStep()59     uint getFrameStep() const { return frame_step; }
60 
setStepSigma(float ss)61     void setStepSigma(float ss) { step_sigma = ss; }
getStepSigma()62     uint getStepSigma() const { return step_sigma; }
63 
setStepSeed(float ss)64     void setStepSeed(float ss) { step_seed = ss; }
getStepSeed()65     uint getStepSeed() const { return step_seed; }
66 
67     void setPattern(const std::string & str);
getPattern()68     const std::string & getPattern() const { return raw_string; }
69 
70     int parse();
71     void printParseResult();
72 
73     const std::string & render(uint frame);
74 
75     uint count() const;
isEnd()76     bool isEnd() const { return last_used_idx == (int)frames.size()-1; }
77 
78     void clear();
debug()79     void debug() const { for (Frame f : frames) f.print(); }
80 
81 private:
82     int parseString(const std::string & line, int start_frame);
83 
84     struct ParseOptions;
85     int parseOptions(const std::string& line, uint & i, ParseOptions & po);
86     int parseMacro(const std::string& line, uint & i, uint & frame);
87 
88     std::string detectUtf8(const std::string & str, size_t pos);
89 
90     void insertChar(char c, uint frame);
91     void insertString(const std::string & str, uint frame);
92     void insertBypass(uint frame);
93 
94     uint getFrameSkipFromOptions(const ParseOptions & po, bool steps = false);
95 
96     uint getOrInsertFrame(uint frame);
97     void addBypass(uint idx);
98 
99 private:
100     size_t frame_rate;
101     size_t frame_step;
102     float step_sigma;
103     size_t step_seed;
104     int parsing_err;
105     int previous_total_frame;
106 
107     std::string raw_string;
108 
109     std::vector<Frame> frames;
110     int last_used_idx;
111 
112     std::mt19937 gen;
113     std::normal_distribution<> d;
114 };
115 
116 class XmlParser
117 {
118 public:
119     XmlParser();
120     virtual ~XmlParser();
121 
122     void setDocument(const char * xml);
123 
124     int parse();
getContentNodesNumber()125     uint getContentNodesNumber() const { return node_vec.size(); }
126 
127     QString getNodeContent(uint i) const;
128     void setNodeContent(uint i, const QString & content);
129 
130     void clear();
131 
132     QString getDocument() const;
133 
134 private:
135     QString doc;
136     QDomDocument dom;
137     QDomNodeList items;
138     std::vector<QDomNode> node_vec;
139 };
140 
141 #endif /* TYPEWRITER_H */
142