3633#if ENABLE(CSS_EXCLUSIONS)
3634PassRefPtr<Shape> CSSParser::parseWrapShapeRect(CSSParserValueList* args)
3635{
3636 ASSERT(args);
3637
3638 // rect(x, y, width, height, [[rx], ry])
3639 if (args->size() != 7 && args->size() != 9 && args->size() != 11)
3640 return 0;
3641
3642 bool valid = true;
3643
3644 RefPtr<RectShape> shape = RectShape::create();
3645
3646 int i = 0;
3647 CSSParserValue* a = args->current();
3648 while (a) {
3649 valid = validUnit(a, FLength, m_strict);
3650 if (!valid)
3651 break;
3652 RefPtr<CSSPrimitiveValue> length = primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);
3653 if (!i)
3654 shape->setLeft(length);
3655 else if (i == 1)
3656 shape->setTop(length);
3657 else if (i == 2)
3658 shape->setWidth(length);
3659 else if (i == 3)
3660 shape->setHeight(length);
3661 else if (i == 4)
3662 shape->setRadiusX(length);
3663 else if (i == 5)
3664 shape->setRadiusY(length);
3665 else {
3666 valid = false;
3667 break;
3668 }
3669 a = args->next();
3670 if (a) {
3671 if (a->unit == CSSParserValue::Operator && a->iValue == ',')
3672 a = args->next();
3673 else {
3674 valid = false;
3675 break;
3676 }
3677 }
3678 i++;
3679 }
3680 if (!valid || i < 4)
3681 return 0;
3682 return shape;
3683}
3684
3685PassRefPtr<Shape> CSSParser::parseWrapShapeCircle(CSSParserValueList* args)
3686{
3687 ASSERT(args);
3688
3689 // circle(x, y, r)
3690 if (args->size() != 5)
3691 return 0;
3692
3693 bool valid = true;
3694
3695 RefPtr<CircleShape> shape = CircleShape::create();
3696
3697 int i = 0;
3698 CSSParserValue* a = args->current();
3699 while (a) {
3700 valid = validUnit(a, FLength, m_strict);
3701 if (!valid)
3702 break;
3703 RefPtr<CSSPrimitiveValue> length = primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);
3704 if (!i)
3705 shape->setLeft(length);
3706 else if (i == 1)
3707 shape->setTop(length);
3708 else if (i == 2)
3709 shape->setRadius(length);
3710 else {
3711 valid = false;
3712 break;
3713 }
3714 a = args->next();
3715 if (a) {
3716 if (a->unit == CSSParserValue::Operator && a->iValue == ',')
3717 a = args->next();
3718 else {
3719 valid = false;
3720 break;
3721 }
3722 }
3723 i++;
3724 }
3725 if (!valid || i < 3)
3726 return 0;
3727 return shape;
3728}
3729
3730PassRefPtr<Shape> CSSParser::parseWrapShapeEllipse(CSSParserValueList* args)
3731{
3732 ASSERT(args);
3733
3734 // ellipse(x, y, rx, ry)
3735 if (args->size() != 7)
3736 return 0;
3737
3738 bool valid = false;
3739
3740 RefPtr<EllipseShape> shape = EllipseShape::create();
3741 int i = 0;
3742 CSSParserValue* a = args->current();
3743 while (a) {
3744 valid = validUnit(a, FLength, m_strict);
3745 if (!valid)
3746 break;
3747 RefPtr<CSSPrimitiveValue> length = primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);
3748 if (!i)
3749 shape->setLeft(length);
3750 else if (i == 1)
3751 shape->setTop(length);
3752 else if (i == 2)
3753 shape->setRadiusX(length);
3754 else if (i == 3)
3755 shape->setRadiusY(length);
3756 else {
3757 valid = false;
3758 break;
3759 }
3760 a = args->next();
3761 if (a) {
3762 if (a && a->unit == CSSParserValue::Operator && a->iValue == ',')
3763 a = args->next();
3764 else {
3765 valid = false;
3766 break;
3767 }
3768 }
3769 i++;
3770 }
3771 if (!valid || i < 4)
3772 return 0;
3773 return shape;
3774}
3775
3776PassRefPtr<Shape> CSSParser::parseWrapShapePolygon(CSSParserValueList* args)
3777{
3778 ASSERT(args);
3779
3780 unsigned size = args->size();
3781 if (!size)
3782 return 0;
3783
3784 RefPtr<PolygonShape> shape = PolygonShape::create();
3785
3786 CSSParserValue* a = args->current();
3787 if (a->id == CSSValueEvenodd || a->id == CSSValueNonzero) {
3788 shape->setWindRule(a->id == CSSValueEvenodd ? RULE_EVENODD : RULE_NONZERO);
3789
3790 CSSParserValue* comma = args->next();
3791 if (!comma || comma->unit != CSSParserValue::Operator || comma->iValue != ',')
3792 return 0;
3793
3794 a = args->next();
3795 size -= 2;
3796 }
3797
3798 // <length>, <length> ... <length>, <length> -> each pair has 3 elements
3799 if (!size || (size % 3))
3800 return 0;
3801
3802 while (a) {
3803 if (!validUnit(a, FLength, m_strict))
3804 return 0;
3805
3806 CSSParserValue* comma = args->next();
3807 if (!comma || comma->unit != CSSParserValue::Operator || comma->iValue != ',')
3808 return 0;
3809
3810 CSSParserValue* b = args->next();
3811 if (!b || !validUnit(b, FLength, m_strict))
3812 return 0;
3813
3814 RefPtr<CSSPrimitiveValue> xLength = primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);
3815 RefPtr<CSSPrimitiveValue> yLength = primitiveValueCache()->createValue(b->fValue, (CSSPrimitiveValue::UnitTypes) b->unit);
3816
3817 shape->appendPoint(xLength.release(), yLength.release());
3818
3819 a = args->next();
3820 }
3821
3822 return shape;
3823}
3824
3825bool CSSParser::parseWrapShape(bool important)
3826{
3827 CSSParserValue* value = m_valueList->current();
3828 CSSParserValueList* args = value->function->args.get();
3829
3830 if (!args)
3831 return false;
3832
3833 RefPtr<Shape> shape;
3834
3835 if (equalIgnoringCase(value->function->name, "rect("))
3836 shape = parseWrapShapeRect(args);
3837 else if (equalIgnoringCase(value->function->name, "circle("))
3838 shape = parseWrapShapeCircle(args);
3839 else if (equalIgnoringCase(value->function->name, "ellipse("))
3840 shape = parseWrapShapeEllipse(args);
3841 else if (equalIgnoringCase(value->function->name, "polygon("))
3842 shape = parseWrapShapePolygon(args);
3843
3844 if (shape) {
3845 addProperty(CSSPropertyWebkitWrapShape, primitiveValueCache()->createValue(shape.release()), important);
3846 m_valueList->next();
3847 return true;
3848 }
3849
3850 return false;
3851}
3852#endif // ENABLE(CSS_EXCLUSIONS)
3853