Home | History | Annotate | Download | only in svg
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #include "SkSVGGradient.h"
     11 #include "SkSVGParser.h"
     12 #include "SkSVGStop.h"
     13 
     14 SkSVGGradient::SkSVGGradient() {
     15 }
     16 
     17 SkSVGElement* SkSVGGradient::getGradient() {
     18     return this;
     19 }
     20 
     21 bool SkSVGGradient::isDef() {
     22     return true;
     23 }
     24 
     25 bool SkSVGGradient::isNotDef() {
     26     return false;
     27 }
     28 
     29 void SkSVGGradient::translate(SkSVGParser& parser, bool defState) {
     30     INHERITED::translate(parser, defState);
     31     // !!! no support for 'objectBoundingBox' yet
     32     bool first = true;
     33     bool addedFirst = false;
     34     bool addedLast = false;
     35     SkString offsets("[");
     36     SkString* lastOffset = NULL;
     37     for (SkSVGElement** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
     38         SkASSERT((*ptr)->getType() == SkSVGType_Stop);
     39         SkSVGStop* stop = (SkSVGStop*) *ptr;
     40         if (first && stop->f_offset.equals("0") == false) {
     41             addedFirst = true;
     42             offsets.append("0,");
     43         }
     44         SkString* thisOffset = &stop->f_offset;
     45         if (lastOffset && thisOffset->equals(*lastOffset)) {
     46             if (thisOffset->equals("1")) {
     47                 offsets.remove(offsets.size() - 2, 2);
     48                 offsets.append(".999,");
     49             } else {
     50                 SkASSERT(0); // !!! need to write this case
     51             }
     52         }
     53         offsets.append(*thisOffset);
     54         if (ptr == fChildren.end() - 1) { // last
     55             if (stop->f_offset.equals("1") == false) {
     56                 offsets.append(",1");
     57                 addedLast = true;
     58             }
     59         } else
     60             offsets.appendUnichar(',');
     61         first = false;
     62         lastOffset = thisOffset;
     63     }
     64     offsets.appendUnichar(']');
     65     parser._addAttribute("offsets", offsets);
     66     if (addedFirst)
     67         parser.translate(*fChildren.begin(), defState);
     68     for (SkSVGElement** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++)
     69         parser.translate(*ptr, defState);
     70     if (addedLast)
     71         parser.translate(*(fChildren.end() - 1), defState);
     72 }
     73 
     74 void SkSVGGradient::translateGradientUnits(SkString& units) {
     75     // !!! no support for 'objectBoundingBox' yet
     76     SkASSERT(strcmp(units.c_str(), "userSpaceOnUse") == 0);
     77 }
     78 
     79 void SkSVGGradient::write(SkSVGParser& parser, SkString& baseColor) {
     80     if (baseColor.c_str()[0] != '#')
     81         return;
     82     SkSVGPaint* saveHead = parser.fHead;
     83     parser.fHead = &fPaintState;
     84     parser.fSuppressPaint = true;
     85     SkString originalID(f_id);
     86     f_id.set("mask"); // write out gradient named given name + color (less initial #)
     87     f_id.append(baseColor.c_str() + 1);
     88     SkString originalColors;
     89     for (SkSVGElement** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
     90         SkSVGStop* colorElement = (SkSVGStop*) *ptr;
     91         SkString& color = colorElement->fPaintState.f_stopColor;
     92         originalColors.append(color);
     93         originalColors.appendUnichar(',');
     94         SkASSERT(color.c_str()[0] == '#');
     95         SkString replacement;
     96         replacement.set("0x");
     97         replacement.append(color.c_str() + 1, 2); // add stop colors using given color, turning existing stop color into alpha
     98         SkASSERT(baseColor.c_str()[0] == '#');
     99         SkASSERT(baseColor.size() == 7);
    100         replacement.append(baseColor.c_str() + 1);
    101         color.set(replacement);
    102     }
    103     translate(parser, true);
    104     const char* originalPtr = originalColors.c_str(); // restore original gradient values
    105     for (SkSVGElement** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
    106         SkSVGStop* color = (SkSVGStop*) *ptr;
    107         const char* originalEnd = strchr(originalPtr, ',');
    108         color->fPaintState.f_stopColor.set(originalPtr, originalEnd - originalPtr);
    109         originalPtr = originalEnd + 1;
    110     }
    111     f_id.set(originalID);
    112     parser.fSuppressPaint = false;
    113     parser.fHead = saveHead;
    114 }
    115