TrafoParser.rl 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. //
  2. // TrafoParser.rl
  3. //
  4. // Created by Marcus Rohrmoser on 11.03.10.
  5. // Copyright (c) 2010-2014, Marcus Rohrmoser mobile Software
  6. // All rights reserved.
  7. //
  8. // Redistribution and use in source and binary forms, with or without modification, are permitted
  9. // provided that the following conditions are met:
  10. //
  11. // 1. Redistributions of source code must retain the above copyright notice, this list of conditions
  12. // and the following disclaimer.
  13. //
  14. // 2. The software must not be used for military or intelligence or related purposes nor
  15. // anything that's in conflict with human rights as declared in http://www.un.org/en/documents/udhr/ .
  16. //
  17. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
  18. // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  19. // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  20. // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  22. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  23. // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  24. // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. //
  26. //
  27. #import "TrafoParser.h"
  28. #include <math.h>
  29. #ifdef MRLogD
  30. #undef MRLogD
  31. #endif
  32. // No Logging
  33. #define MRLogD(x,...)
  34. /** <a href="http://www.complang.org/ragel/">Ragel</a> parser
  35. * for <a href="http://www.w3.org/TR/SVG11/coords.html#TransformAttribute">transform attribute</a> - This file is auto-generated by rl2objc.sh.
  36. * <p>
  37. * DO NOT EDIT MANUALLY!!!
  38. * </p>
  39. */
  40. @implementation TrafoParser
  41. #pragma clang diagnostic push
  42. #pragma clang diagnostic ignored "-Wunused-const-variable"
  43. %%{
  44. machine trafo;
  45. #######################################################
  46. ## Define the actions
  47. #######################################################
  48. action CLEAR {
  49. two = NO;
  50. argc = 0;
  51. }
  52. action TWO {
  53. two = YES;
  54. }
  55. action BUF {
  56. [buf appendFormat:@"%c", *p];
  57. MRLogD(@"buffered '%@'", buf);
  58. }
  59. action NUMBER {
  60. const double v = [buf doubleValue];
  61. MRLogD(@"buffer to number '%@' -> %f", buf, v);
  62. argv[argc++] = v;
  63. [buf setString:@""];
  64. }
  65. action SKEW_X {
  66. if(YES)
  67. [NSException raise:@"Not implemented yet." format:@""];
  68. }
  69. action SKEW_Y {
  70. if(YES)
  71. [NSException raise:@"Not implemented yet." format:@""];
  72. }
  73. action ROTATE {
  74. MRLogD(@"rotate %f", argv[0]);
  75. argv[0] *= M_PI / 180;
  76. if(!two)
  77. t = CGAffineTransformRotate(t, argv[0]);
  78. else
  79. [NSException raise:@"Not implemented yet." format:@""];
  80. // t = CGAffineTransformRotate(t, argv[0]);
  81. // t.rotate(argv[0], argv[1], argv[2]);
  82. }
  83. action SCALE {
  84. if(!two)
  85. argv[1] = argv[0];
  86. MRLogD(@"scale %f,%f", argv[0], argv[1]);
  87. t = CGAffineTransformScale(t, argv[0], argv[1]);
  88. }
  89. action TRANSLATE {
  90. if(!two)
  91. argv[1] = argv[0];
  92. MRLogD(@"translate %f,%f", argv[0], argv[1]);
  93. t = CGAffineTransformTranslate(t, argv[0], argv[1]);
  94. }
  95. action MATRIX {
  96. MRLogD(@"concat", nil);
  97. t = CGAffineTransformConcat(t, CGAffineTransformMake(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]) );
  98. // t.preConcatenate(new AffineTransform(argv));
  99. }
  100. #######################################################
  101. ## Define the grammar
  102. #######################################################
  103. wsp = space;
  104. digit_sequence = digit+;
  105. sign = "+" | "-";
  106. exponent = ( "e" | "E" ) sign? digit_sequence;
  107. fractional_constant = (digit_sequence? "." digit_sequence) | (digit_sequence ".");
  108. floating_point_constant = (fractional_constant exponent?) | (digit_sequence exponent);
  109. integer_constant = digit_sequence;
  110. comma = ",";
  111. comma_wsp = (wsp+ comma? wsp*) | (comma wsp*);
  112. number = (sign? @BUF (integer_constant | floating_point_constant)) @BUF %NUMBER;
  113. skewY = "skewY" wsp* "(" wsp* number wsp* ")" >CLEAR %SKEW_Y;
  114. skewX = "skewX" wsp* "(" wsp* number wsp* ")" >CLEAR %SKEW_X;
  115. rotate = ("rotate" wsp* "(" wsp* number ( comma_wsp number %TWO comma_wsp number )? wsp* ")") >CLEAR %ROTATE;
  116. scale = ("scale" wsp* "(" wsp* number ( comma_wsp number %TWO )? wsp* ")") >CLEAR %SCALE;
  117. translate = ("translate" wsp* "(" wsp* number ( comma_wsp number %TWO )? wsp* ")") >CLEAR %TRANSLATE;
  118. matrix =
  119. "matrix" wsp* "(" wsp*
  120. number comma_wsp
  121. number comma_wsp
  122. number comma_wsp
  123. number comma_wsp
  124. number comma_wsp
  125. number wsp* ")" >CLEAR %MATRIX;
  126. transform =
  127. matrix
  128. | translate
  129. | scale
  130. | rotate
  131. | skewX
  132. | skewY;
  133. transforms =
  134. transform (comma_wsp+ transform)*;
  135. main := wsp* transforms? wsp*;
  136. }%%
  137. %% write data;
  138. -(CGAffineTransform)newCGAffineTransformWithCString:(const char*)data length:(const size_t)length error:(NSError**)errPtr
  139. {
  140. CGAffineTransform t = CGAffineTransformIdentity;
  141. if(data == NULL)
  142. return t;
  143. // high-level buffers
  144. BOOL two = NO;
  145. NSMutableString *buf = [[NSMutableString alloc] init];
  146. double argv[] = {0,0,0,0,0,0};
  147. int argc = 0;
  148. // ragel variables (low level)
  149. const char *p = data;
  150. const char *pe = data + length; // pointer "end"
  151. const char *eof = pe;
  152. int cs = 0;
  153. // int top;
  154. ///////////////////////////////////////////////////////////
  155. // init ragel
  156. %% write init;
  157. ///////////////////////////////////////////////////////////
  158. // exec ragel
  159. %% write exec;
  160. if ( errPtr != nil && cs < trafo_first_final )
  161. *errPtr = [self parseError:data position:p];
  162. return t;
  163. }
  164. -(CGAffineTransform)newCGAffineTransformWithNSString:(NSString*)data error:(NSError**)errPtr
  165. {
  166. const char *c = [data UTF8String];
  167. return [self newCGAffineTransformWithCString:c length:strlen(c) error:errPtr];
  168. }
  169. #pragma clang diagnostic pop
  170. @end