154{
155
156
157 namespace qi = boost::spirit::qi;
158 namespace ascii = boost::spirit::ascii;
159
160 template <typename Iterator>
161 struct transform_unit_parser : qi::grammar<Iterator, std::vector<transform_unit>(), ascii::space_type>
162 {
163 transform_unit_parser() : transform_unit_parser::base_type(start)
164 {
165 namespace phoenix = boost::phoenix;
166 using qi::lit;
167 using qi::double_;
168 using ascii::char_;
169 using qi::cntrl;
170 using phoenix::at_c;
171 using phoenix::push_back;
172 using namespace qi::labels;
173
174
175 comma %= -char_(',');
176
177 matrix_rule %=
178 lit("matrix")
179 >> '('
180 >> double_ >> comma
181 >> double_ >> comma
182 >> double_ >> comma
183 >> double_ >> comma
184 >> double_ >> comma
185 >> double_ >> comma
186 >> ')';
187
188 translate_rule %=
189 lit("translate")
190 >> '(' >> double_ >> comma >> -double_ >> ')';
191
192 scale_rule %=
193 lit("scale")
194 >> '('
195 >> double_ >> comma
196 >> -double_ [at_c<2>(_val) = true]
197 >> ')';
198
199
200
201
202 rotate_rule =
203 lit("rotate")
204 >> '('
205 >> double_ [at_c<0>(_val) = _1]
206 >> comma
207 >> -(double_ [at_c<1>(_val) = _1]
208 >> comma
209 >> double_ [at_c<2>(_val) = _1])
210 >> ')';
211
212 skewX_rule %= lit("skewX") >> '(' >> double_ >> ')';
213 skewY_rule %= lit("skewY") >> '(' >> double_ >> ')';
214
215 start %=
216 (matrix_rule | translate_rule | scale_rule |
217 rotate_rule | skewX_rule | skewY_rule) %
218 (cntrl | comma);
219 }
220
221 qi::rule<Iterator, std::vector<transform_unit>(), ascii::space_type> start;
222 qi::rule<Iterator, translate(), ascii::space_type> translate_rule;
223 qi::rule<Iterator, matrix(), ascii::space_type> matrix_rule;
224 qi::rule<Iterator,
scale(), ascii::space_type> scale_rule;
225 qi::rule<Iterator, rotate(), ascii::space_type> rotate_rule;
226 qi::rule<Iterator, skewX(), ascii::space_type> skewX_rule;
227 qi::rule<Iterator, skewY(), ascii::space_type> skewY_rule;
228 qi::rule<Iterator> comma;
229 };
230}
231
232
234 : m_isValid(false)
235{
236 using boost::spirit::ascii::space;
237 typedef std::string::const_iterator iterator_type;
238 typedef Private::transform_unit_parser<iterator_type> transform_unit_parser;
239
240 transform_unit_parser g;
241 const std::string str = _str.toStdString();
242
243 std::vector<Private::transform_unit> transforms;
244 iterator_type iter = str.begin();
245 iterator_type end = str.end();
246 bool r = phrase_parse(iter, end, g, space, transforms);
247
248 if (r && iter == end) {
249 m_isValid = true;
250
252 m_transform = t.transform * m_transform;
253 }
254 }
255}