Advertisement
KIKIJIKI

Untitled

Oct 6th, 2014
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 23.37 KB | None | 0 0
  1. import java.lang.ref.WeakReference;
  2. import java.util.Random;
  3. import java.util.Stack;
  4.  
  5. import org.xml.sax.Attributes;
  6. import org.xml.sax.SAXException;
  7. import org.xml.sax.helpers.DefaultHandler;
  8.  
  9. import com.kikijiki.ryukisenga.Uti;
  10. import com.kikijiki.ryukisenga.content.SVGUti.SvgTag;
  11. import com.kikijiki.ryukisenga.drawing.Sen;
  12. import com.kikijiki.ryukisenga.drawing.Sequence.Settings;
  13. import com.kikijiki.ryukisenga.drawing.vec;
  14.  
  15. import android.annotation.SuppressLint;
  16. import android.graphics.Matrix;
  17.  
  18. public class SvgContentHandler extends DefaultHandler {
  19.     private final int CIRCLE_ELLIPSE_SEGMENTS_MIN = 4;
  20.     private final static float PI2 = (float) (Math.PI * 2);
  21.  
  22.     private WeakReference<ParserInterface> _thread;
  23.  
  24.     private Stack<Matrix> _transform = new Stack<Matrix>();
  25.     private boolean _abort = false;
  26.     private Random _rnd = new Random();
  27.     private Settings _settings;
  28.  
  29.     private CubicBezierFlattener _flattener;
  30.  
  31.     private class PathData {
  32.         public float previousX = .0f;
  33.         public float previousY = .0f;
  34.  
  35.         public float previousCtpX = .0f;
  36.         public float previousCtpY = .0f;
  37.  
  38.         public float startX = .0f;
  39.         public float startY = .0f;
  40.  
  41.         public char previousCurve = 0;
  42.         public char nextCurve = 0;
  43.     }
  44.  
  45.     private class PathReader {
  46.         private String inputString;
  47.         private int currentPosition = 0;
  48.         private int length = 0;
  49.  
  50.         public PathReader(String string) {
  51.             inputString = string;
  52.             length = inputString.length();
  53.  
  54.             currentPosition = 0;
  55.         }
  56.  
  57.         public boolean hasNext() {
  58.             return currentPosition < length;
  59.         }
  60.  
  61.         public char getNext() {
  62.             return inputString.charAt(currentPosition++);
  63.         }
  64.  
  65.         public char peekNext() {
  66.             return inputString.charAt(currentPosition);
  67.         }
  68.  
  69.         private void skipCharacter() {
  70.             currentPosition++;
  71.         }
  72.  
  73.         private void skipSpaces() {
  74.             while (hasNext()) {
  75.                 char c = peekNext();
  76.  
  77.                 switch (c) {
  78.                     case ' ':
  79.                     case ',':
  80.                     case '\n':
  81.                     case '\t':
  82.                     case '\r':
  83.                         break;
  84.  
  85.                     default:
  86.                         return;
  87.                 }
  88.  
  89.                 skipCharacter();
  90.             }
  91.         }
  92.  
  93.         public float parseFloat() {
  94.             boolean exp = false;
  95.  
  96.             skipSpaces();
  97.  
  98.             int j = currentPosition;
  99.  
  100.             if (inputString.charAt(j) == '-') {
  101.                 getNext();
  102.             }
  103.  
  104.             while (hasNext()) {
  105.                 char c = getNext();
  106.  
  107.                 switch (c) {
  108.                     case '0':
  109.                     case '1':
  110.                     case '2':
  111.                     case '3':
  112.                     case '4':
  113.                     case '5':
  114.                     case '6':
  115.                     case '7':
  116.                     case '8':
  117.                     case '9':
  118.                     case '+':
  119.                     case '.':
  120.                         exp = false;
  121.                         break;
  122.  
  123.                     case '-':
  124.                         if (exp) {
  125.                             exp = false;
  126.                         } else {
  127.                             currentPosition--;
  128.                             return Uti.safeParseFloat(inputString.substring(j, currentPosition));
  129.                         }
  130.                         break;
  131.  
  132.                     case 'e':
  133.                     case 'E':
  134.                         exp = true;
  135.                         break;
  136.  
  137.                     default:
  138.                         currentPosition--;
  139.                         return Uti.safeParseFloat(inputString.substring(j, currentPosition));
  140.                 }
  141.             }
  142.  
  143.             return Uti.safeParseFloat(inputString.substring(j, currentPosition));
  144.         }
  145.     }
  146.  
  147.     public SvgContentHandler(ParserInterface thread, Settings settings) {
  148.         _thread = new WeakReference<ParserInterface>(thread);
  149.  
  150.         Matrix root = new Matrix();
  151.         if (!(settings.viewbox.x < 0 || settings.viewbox.y < 0)) {
  152.             root.setTranslate(-settings.viewbox.x, -settings.viewbox.y);
  153.         }
  154.  
  155.         _transform.push(root);
  156.         _settings = settings;
  157.         _flattener = new CubicBezierConverterFloat(_settings.invScale);
  158.     }
  159.  
  160.     private Matrix getCurrentTransform(Attributes attributes, boolean push) {
  161.         String matrix = SVGUti.getTransform(attributes);
  162.  
  163.         if (matrix == null) {
  164.             if (push) {
  165.                 _transform.push(_transform.peek());
  166.             }
  167.  
  168.             return _transform.peek();
  169.         } else {
  170.             Matrix cur = parseTransform(matrix);
  171.             cur.preConcat(_transform.peek());
  172.  
  173.             if (push) {
  174.                 _transform.push(cur);
  175.             }
  176.  
  177.             return cur;
  178.         }
  179.     }
  180.  
  181.     @SuppressLint("DefaultLocale")
  182.     @Override
  183.     public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
  184.         checkAbort();
  185.  
  186.         SvgTag tag = SvgTag.ignore;
  187.  
  188.         try {
  189.             tag = SvgTag.valueOf(qName.toLowerCase());
  190.         } catch (Exception e) {
  191.             //e.printStackTrace();
  192.         }
  193.  
  194.         switch (tag) {
  195.             case svg:
  196.                 break;
  197.  
  198.             case g:
  199.                 getCurrentTransform(attributes, true);
  200.                 break;
  201.  
  202.             case path: {
  203.                 PathReader reader = new PathReader(SVGUti.getPathData(attributes));
  204.                 PathData pathData = new PathData();
  205.                 PointBuffer pointBuffer = new PointBuffer();
  206.  
  207.                 Matrix matrix = getCurrentTransform(attributes, false);
  208.  
  209.                 while (true) {
  210.                     reader.skipSpaces();
  211.  
  212.                     if (reader.hasNext()) {
  213.                         char c = reader.peekNext();
  214.  
  215.                         if (c >= 'A' && c <= 'z') {
  216.                             pathData.nextCurve = reader.getNext();
  217.                         }
  218.  
  219.                         pointBuffer = parseCurve(reader, pathData, pointBuffer, matrix);
  220.                     } else {
  221.                         break;
  222.                     }
  223.                 }
  224.  
  225.                 if (!pointBuffer.isEmpty())
  226.                     appendElement(pointBuffer);
  227.             }
  228.             break;
  229.  
  230.             case rect: {
  231.                 float x = SVGUti.getRectX(attributes);
  232.                 float y = SVGUti.getRectY(attributes);
  233.                 float w = SVGUti.getRectWidth(attributes);
  234.                 float h = SVGUti.getRectHeight(attributes);
  235.  
  236.                 float xx = x + w;
  237.                 float yy = y + h;
  238.  
  239.                 Matrix m = getCurrentTransform(attributes, false);
  240.  
  241.                 float[] pt = {
  242.                         x, y,
  243.                         xx, y,
  244.                         xx, yy,
  245.                         x, yy,
  246.                         x, y};
  247.  
  248.                 m.mapPoints(pt);
  249.  
  250.                 PointBuffer buffer = new PointBuffer();
  251.                 buffer.append(pt[0], pt[1]);
  252.                 buffer.append(pt[2], pt[3]);
  253.                 buffer.append(pt[4], pt[5]);
  254.                 buffer.append(pt[6], pt[7]);
  255.  
  256.                 appendElement(buffer);
  257.             }
  258.             break;
  259.             case line: {
  260.                 float x1 = SVGUti.getLineX1(attributes);
  261.                 float y1 = SVGUti.getLineY1(attributes);
  262.                 float x2 = SVGUti.getLineX2(attributes);
  263.                 float y2 = SVGUti.getLineY2(attributes);
  264.  
  265.                 Matrix m = getCurrentTransform(attributes, false);
  266.  
  267.                 float[] pt = {x1, y1, x2, y2};
  268.                 m.mapPoints(pt);
  269.  
  270.                 PointBuffer buffer = new PointBuffer();
  271.                 buffer.append(pt[0], pt[1]);
  272.                 buffer.append(pt[2], pt[3]);
  273.  
  274.                 appendElement(buffer);
  275.             }
  276.             break;
  277.  
  278.             case polyline: {
  279.                 appendElement(computePolyline(SVGUti.getPolylinePoints(attributes), false, getCurrentTransform(attributes, false)));
  280.             }
  281.             break;
  282.             case polygon: {
  283.                 appendElement(computePolyline(SVGUti.getPolygonPoints(attributes), true, getCurrentTransform(attributes, false)));
  284.             }
  285.             break;
  286.  
  287.             case circle: {
  288.                 vec cnt = SVGUti.getCircleCnt(attributes);
  289.                 float r = SVGUti.getCircleRadius(attributes);
  290.  
  291.                 appendElement(computeEllipse(r, r, cnt.x, cnt.y, getCurrentTransform(attributes, false)));
  292.             }
  293.             break;
  294.  
  295.             case ellipse: {
  296.                 vec cnt = SVGUti.getEllipseCnt(attributes);
  297.                 vec r = SVGUti.getEllipseRadius(attributes);
  298.  
  299.                 appendElement(computeEllipse(r.x, r.y, cnt.x, cnt.y, getCurrentTransform(attributes, false)));
  300.             }
  301.             break;
  302.  
  303.             case ignore:
  304.                 break;
  305.         }
  306.     }
  307.  
  308.     @SuppressWarnings("unused")
  309.     private PointBuffer parseCurve(PathReader reader, PathData pathData, PointBuffer pointBuffer, Matrix m) throws SAXException {
  310.         pathData.previousCurve = pathData.nextCurve;
  311.  
  312.         switch (pathData.nextCurve) {
  313.             case 'm': {
  314.                 if (!pointBuffer.isEmpty())
  315.                     appendElement(pointBuffer);
  316.  
  317.                 pointBuffer = new PointBuffer();
  318.  
  319.                 pathData.startX = pathData.previousX + reader.parseFloat();
  320.                 pathData.startY = pathData.previousY + reader.parseFloat();
  321.  
  322.                 pathData.previousX = pathData.startX;
  323.                 pathData.previousY = pathData.startY;
  324.  
  325.                 pointBuffer.append(pathData.startX, pathData.startY, m);
  326.  
  327.                 pathData.nextCurve = 'l';
  328.             }
  329.             break;
  330.  
  331.             case 'M': {
  332.                 if (!pointBuffer.isEmpty())
  333.                     appendElement(pointBuffer);
  334.  
  335.                 pointBuffer = new PointBuffer();
  336.  
  337.                 pathData.startX = reader.parseFloat();
  338.                 pathData.startY = reader.parseFloat();
  339.  
  340.                 pathData.previousX = pathData.startX;
  341.                 pathData.previousY = pathData.startY;
  342.  
  343.                 pointBuffer.append(pathData.startX, pathData.startY, m);
  344.  
  345.                 pathData.nextCurve = 'L';
  346.             }
  347.             break;
  348.  
  349.             case 'z':
  350.             case 'Z': {
  351.                 pathData.previousX = pathData.startX;
  352.                 pathData.previousY = pathData.startY;
  353.  
  354.                 pointBuffer.append(pathData.startX, pathData.startY, m);
  355.             }
  356.             break;
  357.  
  358.             case 'h': {
  359.                 float x = pathData.previousX + reader.parseFloat();
  360.  
  361.                 pathData.previousX = x;
  362.  
  363.                 pointBuffer.append(x, pathData.previousY, m);
  364.             }
  365.             break;
  366.  
  367.             case 'H': {
  368.                 float x = reader.parseFloat();
  369.  
  370.                 pathData.previousX = x;
  371.  
  372.                 pointBuffer.append(x, pathData.previousY, m);
  373.             }
  374.             break;
  375.  
  376.             case 'v': {
  377.                 float y = pathData.previousY + reader.parseFloat();
  378.  
  379.                 pathData.previousY = y;
  380.  
  381.                 pointBuffer.append(pathData.previousX, y, m);
  382.             }
  383.             break;
  384.  
  385.             case 'V': {
  386.                 float y = reader.parseFloat();
  387.  
  388.                 pathData.previousY = y;
  389.  
  390.                 pointBuffer.append(pathData.previousX, y, m);
  391.             }
  392.             break;
  393.  
  394.             case 'l': {
  395.                 float x = pathData.previousX + reader.parseFloat();
  396.                 float y = pathData.previousY + reader.parseFloat();
  397.  
  398.                 pathData.previousX = x;
  399.                 pathData.previousY = y;
  400.  
  401.                 pointBuffer.append(x, y, m);
  402.             }
  403.             break;
  404.  
  405.             case 'L': {
  406.                 float x = reader.parseFloat();
  407.                 float y = reader.parseFloat();
  408.  
  409.                 pathData.previousX = x;
  410.                 pathData.previousY = y;
  411.  
  412.                 pointBuffer.append(x, y, m);
  413.             }
  414.             break;
  415.  
  416.             case 'q': {
  417.                 float[] ctp = {.0f, .0f, .0f, .0f, .0f, .0f, .0f, .0f};
  418.  
  419.                 ctp[0] = pathData.previousX;
  420.                 ctp[1] = pathData.previousY;
  421.                 ctp[2] = ctp[0] + reader.parseFloat();
  422.                 ctp[3] = ctp[1] + reader.parseFloat();
  423.                 ctp[4] = ctp[0] + reader.parseFloat();
  424.                 ctp[5] = ctp[1] + reader.parseFloat();
  425.  
  426.                 pathData.previousX = ctp[4];
  427.                 pathData.previousY = ctp[5];
  428.  
  429.                 computeQuadratic(ctp, pointBuffer);
  430.             }
  431.             break;
  432.             case 'Q': {
  433.                 float[] ctp = {.0f, .0f, .0f, .0f, .0f, .0f, .0f, .0f};
  434.  
  435.                 ctp[0] = pathData.previousX;
  436.                 ctp[1] = pathData.previousY;
  437.                 ctp[2] = reader.parseFloat();
  438.                 ctp[3] = reader.parseFloat();
  439.                 ctp[4] = reader.parseFloat();
  440.                 ctp[5] = reader.parseFloat();
  441.  
  442.                 pathData.previousX = ctp[4];
  443.                 pathData.previousY = ctp[5];
  444.  
  445.                 computeQuadratic(ctp, pointBuffer);
  446.             }
  447.             break;
  448.  
  449.             case 't':
  450.                 break;
  451.             case 'T':
  452.                 break;
  453.  
  454.             case 'c': {
  455.                 float[] ctp = {.0f, .0f, .0f, .0f, .0f, .0f, .0f, .0f};
  456.  
  457.                 ctp[0] = pathData.previousX;
  458.                 ctp[1] = pathData.previousY;
  459.                 ctp[2] = ctp[0] + reader.parseFloat();
  460.                 ctp[3] = ctp[1] + reader.parseFloat();
  461.                 ctp[4] = ctp[0] + reader.parseFloat();
  462.                 ctp[5] = ctp[1] + reader.parseFloat();
  463.                 ctp[6] = ctp[0] + reader.parseFloat();
  464.                 ctp[7] = ctp[1] + reader.parseFloat();
  465.  
  466.                 pathData.previousX = ctp[6];
  467.                 pathData.previousY = ctp[7];
  468.                 pathData.previousCtpX = ctp[4];
  469.                 pathData.previousCtpY = ctp[5];
  470.  
  471.                 computeCubic(ctp, pointBuffer);
  472.             }
  473.             break;
  474.             case 'C': {
  475.                 float[] ctp = {.0f, .0f, .0f, .0f, .0f, .0f, .0f, .0f};
  476.  
  477.                 ctp[0] = pathData.previousX;
  478.                 ctp[1] = pathData.previousY;
  479.                 ctp[2] = reader.parseFloat();
  480.                 ctp[3] = reader.parseFloat();
  481.                 ctp[4] = reader.parseFloat();
  482.                 ctp[5] = reader.parseFloat();
  483.                 ctp[6] = reader.parseFloat();
  484.                 ctp[7] = reader.parseFloat();
  485.  
  486.                 pathData.previousX = ctp[6];
  487.                 pathData.previousY = ctp[7];
  488.                 pathData.previousCtpX = ctp[4];
  489.                 pathData.previousCtpY = ctp[5];
  490.  
  491.                 computeCubic(ctp, pointBuffer);
  492.             }
  493.             break;
  494.  
  495.             case 's': {
  496.                 float[] ctp = {.0f, .0f, .0f, .0f, .0f, .0f, .0f, .0f};
  497.  
  498.                 ctp[0] = pathData.previousX;
  499.                 ctp[1] = pathData.previousY;
  500.  
  501.                 if (pathData.previousCurve == 's' || pathData.previousCurve == 'S' || pathData.previousCurve == 'c' || pathData.previousCurve == 'C') {
  502.                     ctp[2] = pathData.previousCtpX;
  503.                     ctp[3] = pathData.previousCtpY;
  504.                 } else {
  505.                     ctp[2] = ctp[0];
  506.                     ctp[3] = ctp[1];
  507.                 }
  508.  
  509.                 ctp[4] = ctp[0] + reader.parseFloat();
  510.                 ctp[5] = ctp[1] + reader.parseFloat();
  511.                 ctp[6] = ctp[0] + reader.parseFloat();
  512.                 ctp[7] = ctp[1] + reader.parseFloat();
  513.  
  514.                 pathData.previousX = ctp[6];
  515.                 pathData.previousY = ctp[7];
  516.                 pathData.previousCtpX = ctp[4];
  517.                 pathData.previousCtpY = ctp[5];
  518.  
  519.                 computeCubic(ctp, pointBuffer);
  520.             }
  521.             break;
  522.  
  523.             case 'S': {
  524.                 float[] ctp = {.0f, .0f, .0f, .0f, .0f, .0f, .0f, .0f};
  525.  
  526.                 ctp[0] = pathData.previousX;
  527.                 ctp[1] = pathData.previousY;
  528.  
  529.                 if (pathData.previousCurve == 's' || pathData.previousCurve == 'S' || pathData.previousCurve == 'c' || pathData.previousCurve == 'C') {
  530.                     ctp[2] = pathData.previousCtpX;
  531.                     ctp[3] = pathData.previousCtpY;
  532.                 } else {
  533.                     ctp[2] = ctp[0];
  534.                     ctp[3] = ctp[1];
  535.                 }
  536.  
  537.                 ctp[4] = reader.parseFloat();
  538.                 ctp[5] = reader.parseFloat();
  539.                 ctp[6] = reader.parseFloat();
  540.                 ctp[7] = reader.parseFloat();
  541.  
  542.                 pathData.previousX = ctp[6];
  543.                 pathData.previousY = ctp[7];
  544.                 pathData.previousCtpX = ctp[4];
  545.                 pathData.previousCtpY = ctp[5];
  546.  
  547.                 computeCubic(ctp, pointBuffer);
  548.             }
  549.             break;
  550.  
  551.             case 'a': {
  552.                 float x0 = pathData.previousX;
  553.                 float y0 = pathData.previousY;
  554.  
  555.                 float rx = reader.parseFloat();
  556.                 float ry = reader.parseFloat();
  557.                 float angle = reader.parseFloat();
  558.                 boolean largeArcFlag = (int) reader.parseFloat() == 1;
  559.                 boolean sweepFlag = (int) reader.parseFloat() == 1;
  560.                 float x = x0 + reader.parseFloat();
  561.                 float y = y0 + reader.parseFloat();
  562.  
  563.                 pathData.previousX = x;
  564.                 pathData.previousY = y;
  565.  
  566.                 pointBuffer.append(x, y); //Arcs not implemented
  567.             }
  568.             break;
  569.  
  570.             case 'A': {
  571.                 float x0 = pathData.previousX;
  572.                 float y0 = pathData.previousY;
  573.  
  574.                 float rx = reader.parseFloat();
  575.                 float ry = reader.parseFloat();
  576.                 float angle = reader.parseFloat();
  577.                 boolean largeArcFlag = (int) reader.parseFloat() == 1;
  578.                 boolean sweepFlag = (int) reader.parseFloat() == 1;
  579.                 float x = reader.parseFloat();
  580.                 float y = reader.parseFloat();
  581.  
  582.                 pathData.previousX = x;
  583.                 pathData.previousY = y;
  584.  
  585.                 pointBuffer.append(x, y); //Arcs not implemented
  586.             }
  587.             break;
  588.  
  589.             default:
  590.                 reader.getNext();
  591.                 break;
  592.         }
  593.  
  594.         return pointBuffer;
  595.     }
  596.  
  597.     private void computeQuadratic(float[] ctp, PointBuffer ptbuf) {
  598.         final float c = 2.0f / 3.0f;
  599.  
  600.         ctp[6] = ctp[4];
  601.         ctp[7] = ctp[5];
  602.         ctp[4] = ctp[4] + c * (ctp[2] - ctp[4]);
  603.         ctp[5] = ctp[5] + c * (ctp[3] - ctp[5]);
  604.         ctp[2] = ctp[0] + c * (ctp[2] - ctp[0]);
  605.         ctp[3] = ctp[1] + c * (ctp[3] - ctp[1]);
  606.  
  607.         computeCubic(ctp, ptbuf);
  608.     }
  609.  
  610.     private void computeCubic(float[] ctp, PointBuffer ptbuf) {
  611.         _transform.peek().mapPoints(ctp);
  612.         _flattener.convert(false, ctp, ptbuf);
  613.     }
  614.  
  615.     PointBuffer computePolyline(String points, boolean close, Matrix m) {
  616.         PointBuffer buf = new PointBuffer();
  617.  
  618.         PathReader reader = new PathReader(points);
  619.  
  620.         while (reader.hasNext()) {
  621.             char c = reader.peekNext();
  622.  
  623.             switch (c) {
  624.                 case ' ':
  625.                 case ',':
  626.                     reader.currentPosition++;
  627.                     break;
  628.  
  629.                 default:
  630.                     buf.append(reader.parseFloat(), reader.parseFloat(), m);
  631.                     break;
  632.             }
  633.         }
  634.  
  635.         if (close) {
  636.             buf.close();
  637.         }
  638.  
  639.         return buf;
  640.     }
  641.  
  642.     private PointBuffer computeEllipse(float rx, float ry, float cntx, float cnty, Matrix m) {
  643.         PointBuffer buf = new PointBuffer();
  644.  
  645.         int div = (int) Math.max(CIRCLE_ELLIPSE_SEGMENTS_MIN, (rx + rx + ry + ry) * _settings.scale * .25f);
  646.  
  647.         float da = PI2 / (float) div;
  648.         float a = da * _rnd.nextInt(div);
  649.  
  650.         for (int i = 0; i < div; i++) {
  651.             float x = (float) (cntx + rx * Math.cos(a));
  652.             float y = (float) (cnty + ry * Math.sin(a));
  653.  
  654.             buf.append(x, y, m);
  655.  
  656.             a += da;
  657.         }
  658.  
  659.         buf.close();
  660.  
  661.         return buf;
  662.     }
  663.  
  664.     private void appendElement(PointBuffer data) throws SAXException {
  665.         checkAbort();
  666.  
  667.         if (data == null || data.pt.size() == 0 || data.len <= Float.MIN_VALUE)
  668.             return;
  669.  
  670.         ParserInterface p = _thread.get();
  671.  
  672.         if (p != null) {
  673.             p.append(new Sen(data, _settings));
  674.         } else {
  675.             _abort = true;
  676.             _thread.clear();
  677.             throw new SAXException("Thread expired.");
  678.         }
  679.     }
  680.  
  681.     private Matrix parseTransform(String mat) {
  682.         int index_first = mat.indexOf(SVGUti.SVG_TRANSFORM_MATRIX_START_BRACKET) + 1;
  683.         int index_last = mat.lastIndexOf(SVGUti.SVG_TRANSFORM_MATRIX_END_BRACKET);
  684.  
  685.         String[] coeff = mat.substring(index_first, index_last).split(SVGUti.SVG_TRANSFORM_MATRIX_COEFF_REGEX);
  686.  
  687.         Matrix ret = new Matrix();
  688.  
  689.         if (mat.startsWith(SVGUti.SVG_TRANSFORM_MATRIX_TYPE_MATRIX)) {
  690.             float[] fcoeff = new float[]{
  691.                     1.0f, .0f, .0f,
  692.                     .0f, 1.0f, .0f,
  693.                     .0f, .0f, 1.0f};
  694.  
  695.             //ref: http://www.w3.org/TR/SVG/coords.html#TransformMatrixDefined
  696.             SVGUti.SafeParse(coeff, 0, fcoeff, 0); //a
  697.             SVGUti.SafeParse(coeff, 1, fcoeff, 3); //c
  698.             SVGUti.SafeParse(coeff, 2, fcoeff, 1); //e
  699.             SVGUti.SafeParse(coeff, 3, fcoeff, 4); //b
  700.             SVGUti.SafeParse(coeff, 4, fcoeff, 2); //d
  701.             SVGUti.SafeParse(coeff, 5, fcoeff, 5); //f
  702.  
  703.             ret.setValues(fcoeff);
  704.         } else if (mat.startsWith(SVGUti.SVG_TRANSFORM_MATRIX_TYPE_TRANSLATE)) {
  705.             float tx = SVGUti.SafeParse(coeff, 0);
  706.             float ty = SVGUti.SafeParse(coeff, 1);
  707.  
  708.             ret.setTranslate(tx, ty);
  709.         } else if (mat.startsWith(SVGUti.SVG_TRANSFORM_MATRIX_TYPE_SCALE)) {
  710.             float sx = SVGUti.SafeParse(coeff, 0);
  711.             float sy = SVGUti.SafeParse(coeff, 1);
  712.  
  713.             ret.setScale(sx, sy);
  714.         } else if (mat.startsWith(SVGUti.SVG_TRANSFORM_MATRIX_TYPE_ROTATE)) {
  715.             float a = SVGUti.SafeParse(coeff, 0);
  716.             float cx = SVGUti.SafeParse(coeff, 1);
  717.             float cy = SVGUti.SafeParse(coeff, 2);
  718.  
  719.             ret.setRotate(a, cx, cy);
  720.         } else if (mat.startsWith(SVGUti.SVG_TRANSFORM_MATRIX_TYPE_SKEWX)) {
  721.             float sk = SVGUti.SafeParse(coeff, 0);
  722.  
  723.             ret.setSkew(sk, .0f);
  724.         } else if (mat.startsWith(SVGUti.SVG_TRANSFORM_MATRIX_TYPE_SKEWY)) {
  725.             float sk = SVGUti.SafeParse(coeff, 0);
  726.  
  727.             ret.setSkew(.0f, sk);
  728.         }
  729.  
  730.         return ret;
  731.     }
  732.  
  733.     @Override
  734.     public void endElement(String uri, String localName, String qName) throws SAXException {
  735.         if (qName.equalsIgnoreCase("g")) {
  736.             _transform.pop();
  737.         }
  738.     }
  739.  
  740.     public void abort() {
  741.         _abort = true;
  742.     }
  743.  
  744.     private void checkAbort() throws SAXException {
  745.         if (_abort || Thread.interrupted())
  746.             throw new SAXException("Aborted by the loading thread.");
  747.     }
  748. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement