コード例 #1
0
    //==============================================================================
    Drawable* parseSVGElement (const XmlPath& xml)
    {
        if (! xml->hasTagNameIgnoringNamespace ("svg"))
            return nullptr;

        DrawableComposite* const drawable = new DrawableComposite();

        setDrawableID (*drawable, xml);

        SVGState newState (*this);

        if (xml->hasAttribute ("transform"))
            newState.addTransform (xml);

        newState.elementX = getCoordLength (xml->getStringAttribute ("x",      String (newState.elementX)), viewBoxW);
        newState.elementY = getCoordLength (xml->getStringAttribute ("y",      String (newState.elementY)), viewBoxH);
        newState.width    = getCoordLength (xml->getStringAttribute ("width",  String (newState.width)),    viewBoxW);
        newState.height   = getCoordLength (xml->getStringAttribute ("height", String (newState.height)),   viewBoxH);

        if (newState.width  <= 0) newState.width  = 100;
        if (newState.height <= 0) newState.height = 100;

        Point<float> viewboxXY;

        if (xml->hasAttribute ("viewBox"))
        {
            const String viewBoxAtt (xml->getStringAttribute ("viewBox"));
            String::CharPointerType viewParams (viewBoxAtt.getCharPointer());
            Point<float> vwh;

            if (parseCoords (viewParams, viewboxXY, true)
                 && parseCoords (viewParams, vwh, true)
                 && vwh.x > 0
                 && vwh.y > 0)
            {
                newState.viewBoxW = vwh.x;
                newState.viewBoxH = vwh.y;

                int placementFlags = 0;

                const String aspect (xml->getStringAttribute ("preserveAspectRatio"));

                if (aspect.containsIgnoreCase ("none"))
                {
                    placementFlags = RectanglePlacement::stretchToFit;
                }
                else
                {
                    if (aspect.containsIgnoreCase ("slice"))        placementFlags |= RectanglePlacement::fillDestination;

                    if (aspect.containsIgnoreCase ("xMin"))         placementFlags |= RectanglePlacement::xLeft;
                    else if (aspect.containsIgnoreCase ("xMax"))    placementFlags |= RectanglePlacement::xRight;
                    else                                            placementFlags |= RectanglePlacement::xMid;

                    if (aspect.containsIgnoreCase ("yMin"))         placementFlags |= RectanglePlacement::yTop;
                    else if (aspect.containsIgnoreCase ("yMax"))    placementFlags |= RectanglePlacement::yBottom;
                    else                                            placementFlags |= RectanglePlacement::yMid;
                }

                newState.transform = RectanglePlacement (placementFlags)
                                        .getTransformToFit (Rectangle<float> (viewboxXY.x, viewboxXY.y, vwh.x, vwh.y),
                                                            Rectangle<float> (newState.width, newState.height))
                                        .followedBy (newState.transform);
            }
        }
        else
        {
            if (viewBoxW == 0)  newState.viewBoxW = newState.width;
            if (viewBoxH == 0)  newState.viewBoxH = newState.height;
        }

        newState.parseSubElements (xml, *drawable);

        drawable->setContentArea (RelativeRectangle (RelativeCoordinate (viewboxXY.x),
                                                     RelativeCoordinate (viewboxXY.x + newState.viewBoxW),
                                                     RelativeCoordinate (viewboxXY.y),
                                                     RelativeCoordinate (viewboxXY.y + newState.viewBoxH)));
        drawable->resetBoundingBoxToContentArea();

        return drawable;
    }
コード例 #2
0
    //==============================================================================
    Drawable* parseSVGElement (const XmlElement& xml)
    {
        if (! xml.hasTagName ("svg"))
            return nullptr;

        DrawableComposite* const drawable = new DrawableComposite();

        drawable->setName (xml.getStringAttribute ("id"));

        SVGState newState (*this);

        if (xml.hasAttribute ("transform"))
            newState.addTransform (xml);

        newState.elementX = getCoordLength (xml.getStringAttribute ("x", String (newState.elementX)), viewBoxW);
        newState.elementY = getCoordLength (xml.getStringAttribute ("y", String (newState.elementY)), viewBoxH);
        newState.width    = getCoordLength (xml.getStringAttribute ("width", String (newState.width)), viewBoxW);
        newState.height   = getCoordLength (xml.getStringAttribute ("height", String (newState.height)), viewBoxH);

        if (newState.width <= 0)  newState.width  = 100;
        if (newState.height <= 0) newState.height = 100;

        if (xml.hasAttribute ("viewBox"))
        {
            const String viewBoxAtt (xml.getStringAttribute ("viewBox"));
            String::CharPointerType viewParams (viewBoxAtt.getCharPointer());
            float vx, vy, vw, vh;

            if (parseCoords (viewParams, vx, vy, true)
                 && parseCoords (viewParams, vw, vh, true)
                 && vw > 0
                 && vh > 0)
            {
                newState.viewBoxW = vw;
                newState.viewBoxH = vh;

                int placementFlags = 0;

                const String aspect (xml.getStringAttribute ("preserveAspectRatio"));

                if (aspect.containsIgnoreCase ("none"))
                {
                    placementFlags = RectanglePlacement::stretchToFit;
                }
                else
                {
                    if (aspect.containsIgnoreCase ("slice"))
                        placementFlags |= RectanglePlacement::fillDestination;

                    if (aspect.containsIgnoreCase ("xMin"))
                        placementFlags |= RectanglePlacement::xLeft;
                    else if (aspect.containsIgnoreCase ("xMax"))
                        placementFlags |= RectanglePlacement::xRight;
                    else
                        placementFlags |= RectanglePlacement::xMid;

                    if (aspect.containsIgnoreCase ("yMin"))
                        placementFlags |= RectanglePlacement::yTop;
                    else if (aspect.containsIgnoreCase ("yMax"))
                        placementFlags |= RectanglePlacement::yBottom;
                    else
                        placementFlags |= RectanglePlacement::yMid;
                }

                const RectanglePlacement placement (placementFlags);

                newState.transform
                    = placement.getTransformToFit (Rectangle<float> (vx, vy, vw, vh),
                                                   Rectangle<float> (0.0f, 0.0f, newState.width, newState.height))
                               .followedBy (newState.transform);
            }
        }
        else
        {
            if (viewBoxW == 0)
                newState.viewBoxW = newState.width;

            if (viewBoxH == 0)
                newState.viewBoxH = newState.height;
        }

        newState.parseSubElements (xml, drawable);

        drawable->resetContentAreaAndBoundingBoxToFitChildren();
        return drawable;
    }