public boolean isSpecified(RenderingRuleProperty property) {
   if (property.isFloat()) {
     return fvalues[property.getId()] != 0 || values[property.getId()] != -1;
   } else {
     int val = values[property.getId()];
     if (property.isColor()) {
       return val != 0;
     } else {
       return val != -1;
     }
   }
 }
 public float getFloatPropertyValue(RenderingRuleProperty property, float defVal) {
   float f = fvalues[property.getId()];
   if (f == 0) {
     return defVal;
   }
   return f;
 }
 public String getStringPropertyValue(RenderingRuleProperty property) {
   int val = values[property.getId()];
   if (val < 0) {
     return null;
   }
   return storage.getStringValue(val);
 }
 public void clearValue(RenderingRuleProperty p) {
   if (p.isIntParse()) {
     values[p.getId()] = savedValues[p.getId()];
   } else {
     fvalues[p.getId()] = savedFvalues[p.getId()];
     values[p.getId()] = savedValues[p.getId()];
   }
 }
  private boolean visitRule(RenderingRule rule, boolean loadOutput) {
    RenderingRuleProperty[] properties = rule.getProperties();
    for (int i = 0; i < properties.length; i++) {
      RenderingRuleProperty rp = properties[i];
      if (rp.isInputProperty()) {
        boolean match;
        if (rp.isFloat()) {
          match = rp.accept(rule.getFloatProp(i), fvalues[rp.getId()], this);
        } else {
          match = rp.accept(rule.getIntProp(i), values[rp.getId()], this);
        }
        if (!match) {
          return false;
        }
      } else if (rp == storage.PROPS.R_DISABLE) {
        // quick disable return even without load output
        values[rp.getId()] = rule.getIntProp(i);
      }
    }
    if (!loadOutput) {
      return true;
    }
    // accept it
    for (int i = 0; i < properties.length; i++) {
      RenderingRuleProperty rp = properties[i];
      if (rp.isOutputProperty()) {
        searchResult = true;
        if (rp.isFloat()) {
          fvalues[rp.getId()] = rule.getFloatProp(i);
          values[rp.getId()] = rule.getIntProp(i);
        } else {
          values[rp.getId()] = rule.getIntProp(i);
        }
      }
    }

    for (RenderingRule rr : rule.getIfElseChildren()) {
      boolean match = visitRule(rr, loadOutput);
      if (match) {
        break;
      }
    }

    for (RenderingRule rr : rule.getIfChildren()) {
      visitRule(rr, loadOutput);
    }
    return true;
  }
 public void setBooleanFilter(RenderingRuleProperty p, boolean filter) {
   assert p.isInputProperty();
   values[p.getId()] =
       filter ? RenderingRuleProperty.TRUE_VALUE : RenderingRuleProperty.FALSE_VALUE;
 }
 public void setIntFilter(RenderingRuleProperty p, int filter) {
   assert p.isInputProperty();
   values[p.getId()] = filter;
 }
 public void setStringFilter(RenderingRuleProperty p, String filter) {
   assert p.isInputProperty();
   values[p.getId()] = storage.getDictionaryValue(filter);
 }
 public int getIntPropertyValue(RenderingRuleProperty property, int defValue) {
   int val = values[property.getId()];
   return val == -1 ? defValue : val;
 }
 public int getIntPropertyValue(RenderingRuleProperty property) {
   return values[property.getId()];
 }
 public String getColorStringPropertyValue(RenderingRuleProperty property) {
   return RenderingRuleProperty.colorToString(values[property.getId()]);
 }
 public float getFloatPropertyValue(RenderingRuleProperty property) {
   return fvalues[property.getId()];
 }