Exemplo n.º 1
0
bool SkSVGElement::isGroupParent() {
    SkSVGElement* parent = fParent;
    while (parent) {
        if (parent->getType() != SkSVGType_G)
            return false;
        parent = parent->fParent;
    }
    return true;
}
Exemplo n.º 2
0
bool SkSVGParser::onEndElement(const char elem[]) {
    int parentIndex = fParents.count() - 1;
    if (parentIndex >= 0) {
        SkSVGElement* element = fParents[parentIndex];
        element->onEndElement(*this);
        fParents.remove(parentIndex);
    }
    return false;
}
Exemplo n.º 3
0
SkSVGElement* SkSVGParser::CreateElement(SkSVGTypes type, SkSVGElement* parent) {
    SkSVGElement* created = NULL;
    switch (type) {
        CASE_NEW(Circle);
        CASE_NEW(ClipPath);
        CASE_NEW(Defs);
        CASE_NEW(Ellipse);
        CASE_NEW(FeColorMatrix);
        CASE_NEW(Filter);
        CASE_NEW(G);
        CASE_NEW(Image);
        CASE_NEW(Line);
        CASE_NEW(LinearGradient);
        CASE_NEW(Mask);
        CASE_NEW(Metadata);
        CASE_NEW(Path);
        CASE_NEW(Polygon);
        CASE_NEW(Polyline);
        CASE_NEW(RadialGradient);
        CASE_NEW(Rect);
        CASE_NEW(Stop);
        CASE_NEW(SVG);
        CASE_NEW(Symbol);
        CASE_NEW(Text);
        CASE_NEW(Tspan);
        CASE_NEW(Use);
        default:
            SkASSERT(0);
            return NULL;
    }
    created->fParent = parent;
    bool isDef = created->fIsDef = created->isDef();
    bool isNotDef = created->fIsNotDef = created->isNotDef();
    if (isDef) {
        SkSVGElement* up = parent;
        while (up && up->fIsDef == false) {
            up->fIsDef = true;
            up = up->fParent;
        }
    }
    if (isNotDef) {
        SkSVGElement* up = parent;
        while (up && up->fIsNotDef == false) {
            up->fIsNotDef = true;
            up = up->fParent;
        }
    }
    return created;
}
void SkSVGClipPath::translate(SkSVGParser& parser, bool defState) {
    parser._startElement("clip");
    INHERITED::translate(parser, defState);
    SkASSERT(fChildren.count() == 1);
    SkSVGElement* child = *fChildren.begin();
    SkASSERT(child->getType() == SkSVGType_Use);
    SkSVGUse* use = (SkSVGUse*) child;
    SkSVGElement* ref = NULL;
    const char* refStr = &use->f_xlink_href.c_str()[1];
    SkASSERT(parser.getIDs().find(refStr, &ref));
    SkASSERT(ref);
    if (ref->getType() == SkSVGType_Rect) 
        parser._addAttribute("rectangle", refStr);
    else
        parser._addAttribute("path", refStr);
    parser._endElement();
}
bool SkSVGPaint::writeChangedAttributes(SkSVGParser& parser,
        SkSVGPaint& current, bool* changed) {
    SkSVGPaint& lastState = parser.fLastFlush;
    for (int index = kInitial + 1; index < kTerminal; index++) {
        if (changed[index] == false)
                continue;
        SkString* topAttr = current[index];
        size_t attrLength = topAttr->size();
        if (attrLength == 0)
            continue;
        const char* attrValue = topAttr->c_str();
        SkString* lastAttr = lastState[index];
        switch(index) {
            case kClipPath:
            case kClipRule:
            case kEnableBackground:
                break;
            case kFill:
                if (topAttr->equals("none") == false && lastAttr->equals("none") == true)
                    parser._addAttribute("stroke", "false");
                goto fillStrokeAttrCommon;
            case kFillRule:
            case kFilter:
            case kFontFamily:
                break;
            case kFontSize:
                parser._addAttributeLen("textSize", attrValue, attrLength);
                break;
            case kLetterSpacing:
                parser._addAttributeLen("textTracking", attrValue, attrLength);
                break;
            case kMask:
                break;
            case kOpacity:
                break;
            case kStopColor:
                break;
            case kStopOpacity:
                break;
            case kStroke:
                if (topAttr->equals("none") == false && lastAttr->equals("none") == true)
                    parser._addAttribute("stroke", "true");
fillStrokeAttrCommon:
                if (strncmp(attrValue, "url(", 4) == 0) {
                    SkASSERT(attrValue[4] == '#');
                    const char* idStart = attrValue + 5;
                    const char* idEnd = strrchr(attrValue, ')');
                    SkASSERT(idStart < idEnd);
                    SkString id(idStart, idEnd - idStart);
                    SkSVGElement* found;
                    if (strncmp(id.c_str(), "mask", 4) != 0) {
                        bool itsFound = parser.fIDs.find(id.c_str(), &found);
                        SkASSERT(itsFound);
                        SkASSERT(found->getType() == SkSVGType_LinearGradient ||
                            found->getType() == SkSVGType_RadialGradient);
                    }
                    parser._addAttribute("shader", id.c_str());
                }
                break;
            case kStroke_Dasharray:
                break;
            case kStroke_Linecap:
                parser._addAttributeLen("strokeCap", attrValue, attrLength);
                break;
            case kStroke_Linejoin:
                parser._addAttributeLen("strokeJoin", attrValue, attrLength);
                break;
            case kStroke_Miterlimit:
                parser._addAttributeLen("strokeMiter", attrValue, attrLength);
                break;
            case kStroke_Width:
                parser._addAttributeLen("strokeWidth", attrValue, attrLength);
            case kStyle:
            case kTransform:
                break;
        default:
            SkASSERT(0);
            return false;
        }
    }
    return true;
}
bool SkSVGPaint::flush(SkSVGParser& parser, bool isFlushable, bool isDef) {
    SkSVGPaint current;
    SkSVGPaint* walking = parser.fHead;
    int index;
    while (walking != NULL) {
        for (index = kInitial + 1; index < kTerminal; index++) {
            SkString* lastAttr = (*walking)[index];
            if (lastAttr->size() == 0)
                continue;
            if (current[index]->size() > 0)
                continue;
            current[index]->set(*lastAttr);
        }
        walking = walking->fNext;
    }
    bool paintChanged = false;
    SkSVGPaint& lastState = parser.fLastFlush;
    if (isFlushable == false) {
        if (isDef == true) {
            if (current.f_mask.size() > 0 && current.f_mask.equals(lastState.f_mask) == false) {
                SkSVGElement* found;
                const char* idStart = strchr(current.f_mask.c_str(), '#');
                SkASSERT(idStart);
                SkString id(idStart + 1, strlen(idStart) - 2);
                bool itsFound = parser.fIDs.find(id.c_str(), &found);
                SkASSERT(itsFound);
                SkSVGElement* gradient = found->getGradient();
                if (gradient) {
                    gradient->write(parser, current.f_fill);
                    gradient->write(parser, current.f_stroke);
                }
            }
        }
        goto setLast;
    }
    {
        bool changed[kTerminal];
        memset(changed, 0, sizeof(changed));
        for (index = kInitial + 1; index < kTerminal; index++) {
            if (index == kTransform || index == kClipPath || index == kStopColor || index == kStopOpacity ||
                    index == kClipRule || index == kFillRule)
                continue;
            SkString* lastAttr = lastState[index];
            SkString* currentAttr = current[index];
            paintChanged |= changed[index] = lastAttr->equals(*currentAttr) == false;
        }
        if (paintChanged) {
            if (current.f_mask.size() > 0) {
                if (current.f_fill.equals("none") == false && strncmp(current.f_fill.c_str(), "url(#", 5) != 0) {
                    SkASSERT(current.f_fill.c_str()[0] == '#');
                    SkString replacement("url(#mask");
                    replacement.append(current.f_fill.c_str() + 1);
                    replacement.appendUnichar(')');
                    current.f_fill.set(replacement);
                }
                if (current.f_stroke.equals("none") == false && strncmp(current.f_stroke.c_str(), "url(#", 5) != 0) {
                    SkASSERT(current.f_stroke.c_str()[0] == '#');
                    SkString replacement("url(#mask");
                    replacement.append(current.f_stroke.c_str() + 1);
                    replacement.appendUnichar(')');
                    current.f_stroke.set(replacement);
                }
            }
            if (current.f_fill.equals("none") && current.f_stroke.equals("none"))
                current.f_opacity.set("0");
            if (parser.fSuppressPaint == false) {
                parser._startElement("paint");
                bool success = writeChangedAttributes(parser, current, changed);
                if (success == false)
                    return paintChanged;
                success = writeChangedElements(parser, current, changed);
                if (success == false)
                    return paintChanged;
                parser._endElement(); // paint
            }
        }
    }
setLast:
    for (index = kInitial + 1; index < kTerminal; index++) {
        SkString* lastAttr = lastState[index];
        SkString* currentAttr = current[index];
        lastAttr->set(*currentAttr);
    }
    return paintChanged;
}