public String getAttr(String name) {
   String v = null;
   if (styles != null) {
     v = styles.getStyle(name);
   }
   if (v == null) {
     v = getStringAttr(name, atts);
   }
   return v;
 }
 @Override
 public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
     throws SAXException {
   // Reset paint opacity
   paint.setAlpha(255);
   // Ignore everything but rectangles in bounds mode
   if (boundsMode) {
     if (localName.equals("rect")) {
       Float x = getFloatAttr("x", atts);
       if (x == null) {
         x = 0f;
       }
       Float y = getFloatAttr("y", atts);
       if (y == null) {
         y = 0f;
       }
       Float width = getFloatAttr("width", atts);
       Float height = getFloatAttr("height", atts);
       bounds = new RectF(x, y, x + width, y + height);
     }
     return;
   }
   if (localName.equals("svg")) {
     int width = (int) Math.ceil(getFloatAttr("width", atts));
     int height = (int) Math.ceil(getFloatAttr("height", atts));
     canvas = picture.beginRecording(width, height);
   } else if (localName.equals("defs")) {
     // Ignore
   } else if (localName.equals("linearGradient")) {
     gradient = doGradient(true, atts);
   } else if (localName.equals("radialGradient")) {
     gradient = doGradient(false, atts);
   } else if (localName.equals("stop")) {
     if (gradient != null) {
       float offset = getFloatAttr("offset", atts);
       String styles = getStringAttr("style", atts);
       StyleSet styleSet = new StyleSet(styles);
       String colorStyle = styleSet.getStyle("stop-color");
       int color = Color.BLACK;
       if (colorStyle != null) {
         if (colorStyle.startsWith("#")) {
           color = Integer.parseInt(colorStyle.substring(1), 16);
         } else {
           color = Integer.parseInt(colorStyle, 16);
         }
       }
       String opacityStyle = styleSet.getStyle("stop-opacity");
       if (opacityStyle != null) {
         float alpha = Float.parseFloat(opacityStyle);
         int alphaInt = Math.round(255 * alpha);
         color |= (alphaInt << 24);
       } else {
         color |= 0xFF000000;
       }
       gradient.positions.add(offset);
       gradient.colors.add(color);
     }
   } else if (localName.equals("g")) {
     // Check to see if this is the "bounds" layer
     if ("bounds".equalsIgnoreCase(getStringAttr("id", atts))) {
       boundsMode = true;
     }
     if (hidden) {
       hiddenLevel++;
       // Util.debug("Hidden up: " + hiddenLevel);
     }
     // Go in to hidden mode if display is "none"
     if ("none".equals(getStringAttr("display", atts))) {
       if (!hidden) {
         hidden = true;
         hiddenLevel = 1;
         // Util.debug("Hidden up: " + hiddenLevel);
       }
     }
     pushTransform(atts);
   } else if (!hidden && localName.equals("rect")) {
     Float x = getFloatAttr("x", atts);
     if (x == null) {
       x = 0f;
     }
     Float y = getFloatAttr("y", atts);
     if (y == null) {
       y = 0f;
     }
     Float width = getFloatAttr("width", atts);
     Float height = getFloatAttr("height", atts);
     Float rx = getFloatAttr("rx", atts);
     Float ry = getFloatAttr("ry", atts);
     if (rx == null) {
       if (ry == null) rx = ry = 0f;
       else rx = ry;
     } else {
       if (ry == null) ry = rx;
     }
     if (rx > width / 2) rx = width * 0.5f;
     if (ry > height / 2) ry = height * 0.5f;
     pushTransform(atts);
     Properties props = new Properties(atts);
     if (doFill(props, gradientMap)) {
       doLimits(x, y, width, height);
       if (rx > 0 && ry > 0)
         canvas.drawRoundRect(new RectF(x, y, x + width, y + height), rx, ry, paint);
       else canvas.drawRect(x, y, x + width, y + height, paint);
     }
     if (doStroke(props, gradientMap)) {
       if (rx > 0 && ry > 0)
         canvas.drawRoundRect(new RectF(x, y, x + width, y + height), rx, ry, paint);
       else canvas.drawRect(x, y, x + width, y + height, paint);
     }
     popTransform();
   } else if (!hidden && localName.equals("line")) {
     Float x1 = getFloatAttr("x1", atts);
     Float x2 = getFloatAttr("x2", atts);
     Float y1 = getFloatAttr("y1", atts);
     Float y2 = getFloatAttr("y2", atts);
     Properties props = new Properties(atts);
     if (doStroke(props, gradientMap)) {
       pushTransform(atts);
       doLimits(x1, y1);
       doLimits(x2, y2);
       canvas.drawLine(x1, y1, x2, y2, paint);
       popTransform();
     }
   } else if (!hidden && localName.equals("circle")) {
     Float centerX = getFloatAttr("cx", atts);
     Float centerY = getFloatAttr("cy", atts);
     Float radius = getFloatAttr("r", atts);
     if (centerX != null && centerY != null && radius != null) {
       pushTransform(atts);
       Properties props = new Properties(atts);
       if (doFill(props, gradientMap)) {
         doLimits(centerX - radius, centerY - radius);
         doLimits(centerX + radius, centerY + radius);
         canvas.drawCircle(centerX, centerY, radius, paint);
       }
       if (doStroke(props, gradientMap)) {
         canvas.drawCircle(centerX, centerY, radius, paint);
       }
       popTransform();
     }
   } else if (!hidden && localName.equals("ellipse")) {
     Float centerX = getFloatAttr("cx", atts);
     Float centerY = getFloatAttr("cy", atts);
     Float radiusX = getFloatAttr("rx", atts);
     Float radiusY = getFloatAttr("ry", atts);
     if (centerX != null && centerY != null && radiusX != null && radiusY != null) {
       pushTransform(atts);
       Properties props = new Properties(atts);
       rect.set(centerX - radiusX, centerY - radiusY, centerX + radiusX, centerY + radiusY);
       if (doFill(props, gradientMap)) {
         doLimits(centerX - radiusX, centerY - radiusY);
         doLimits(centerX + radiusX, centerY + radiusY);
         canvas.drawOval(rect, paint);
       }
       if (doStroke(props, gradientMap)) {
         canvas.drawOval(rect, paint);
       }
       popTransform();
     }
   } else if (!hidden && (localName.equals("polygon") || localName.equals("polyline"))) {
     NumberParse numbers = getNumberParseAttr("points", atts);
     if (numbers != null) {
       Path p = new Path();
       ArrayList<Float> points = numbers.numbers;
       if (points.size() > 1) {
         pushTransform(atts);
         Properties props = new Properties(atts);
         p.moveTo(points.get(0), points.get(1));
         for (int i = 2; i < points.size(); i += 2) {
           float x = points.get(i);
           float y = points.get(i + 1);
           p.lineTo(x, y);
         }
         // Don't close a polyline
         if (localName.equals("polygon")) {
           p.close();
         }
         if (doFill(props, gradientMap)) {
           doLimits(p);
           canvas.drawPath(p, paint);
         }
         if (doStroke(props, gradientMap)) {
           canvas.drawPath(p, paint);
         }
         popTransform();
       }
     }
   } else if (!hidden && localName.equals("path")) {
     Path p = doPath(getStringAttr("d", atts));
     pushTransform(atts);
     Properties props = new Properties(atts);
     if (doFill(props, gradientMap)) {
       doLimits(p);
       canvas.drawPath(p, paint);
     }
     if (doStroke(props, gradientMap)) {
       canvas.drawPath(p, paint);
     }
     popTransform();
   } else if (!hidden) {
     //                Log.d(TAG, "UNRECOGNIZED SVG COMMAND: " + localName);
   }
 }