michael@0: michael@0: /* michael@0: * Copyright 2006 The Android Open Source Project michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: michael@0: #include "SkSVGGradient.h" michael@0: #include "SkSVGParser.h" michael@0: #include "SkSVGStop.h" michael@0: michael@0: SkSVGGradient::SkSVGGradient() { michael@0: } michael@0: michael@0: SkSVGElement* SkSVGGradient::getGradient() { michael@0: return this; michael@0: } michael@0: michael@0: bool SkSVGGradient::isDef() { michael@0: return true; michael@0: } michael@0: michael@0: bool SkSVGGradient::isNotDef() { michael@0: return false; michael@0: } michael@0: michael@0: void SkSVGGradient::translate(SkSVGParser& parser, bool defState) { michael@0: INHERITED::translate(parser, defState); michael@0: // !!! no support for 'objectBoundingBox' yet michael@0: bool first = true; michael@0: bool addedFirst = false; michael@0: bool addedLast = false; michael@0: SkString offsets("["); michael@0: SkString* lastOffset = NULL; michael@0: for (SkSVGElement** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { michael@0: SkASSERT((*ptr)->getType() == SkSVGType_Stop); michael@0: SkSVGStop* stop = (SkSVGStop*) *ptr; michael@0: if (first && stop->f_offset.equals("0") == false) { michael@0: addedFirst = true; michael@0: offsets.append("0,"); michael@0: } michael@0: SkString* thisOffset = &stop->f_offset; michael@0: if (lastOffset && thisOffset->equals(*lastOffset)) { michael@0: if (thisOffset->equals("1")) { michael@0: offsets.remove(offsets.size() - 2, 2); michael@0: offsets.append(".999,"); michael@0: } else { michael@0: SkASSERT(0); // !!! need to write this case michael@0: } michael@0: } michael@0: offsets.append(*thisOffset); michael@0: if (ptr == fChildren.end() - 1) { // last michael@0: if (stop->f_offset.equals("1") == false) { michael@0: offsets.append(",1"); michael@0: addedLast = true; michael@0: } michael@0: } else michael@0: offsets.appendUnichar(','); michael@0: first = false; michael@0: lastOffset = thisOffset; michael@0: } michael@0: offsets.appendUnichar(']'); michael@0: parser._addAttribute("offsets", offsets); michael@0: if (addedFirst) michael@0: parser.translate(*fChildren.begin(), defState); michael@0: for (SkSVGElement** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) michael@0: parser.translate(*ptr, defState); michael@0: if (addedLast) michael@0: parser.translate(*(fChildren.end() - 1), defState); michael@0: } michael@0: michael@0: void SkSVGGradient::translateGradientUnits(SkString& units) { michael@0: // !!! no support for 'objectBoundingBox' yet michael@0: SkASSERT(strcmp(units.c_str(), "userSpaceOnUse") == 0); michael@0: } michael@0: michael@0: void SkSVGGradient::write(SkSVGParser& parser, SkString& baseColor) { michael@0: if (baseColor.c_str()[0] != '#') michael@0: return; michael@0: SkSVGPaint* saveHead = parser.fHead; michael@0: parser.fHead = &fPaintState; michael@0: parser.fSuppressPaint = true; michael@0: SkString originalID(f_id); michael@0: f_id.set("mask"); // write out gradient named given name + color (less initial #) michael@0: f_id.append(baseColor.c_str() + 1); michael@0: SkString originalColors; michael@0: for (SkSVGElement** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { michael@0: SkSVGStop* colorElement = (SkSVGStop*) *ptr; michael@0: SkString& color = colorElement->fPaintState.f_stopColor; michael@0: originalColors.append(color); michael@0: originalColors.appendUnichar(','); michael@0: SkASSERT(color.c_str()[0] == '#'); michael@0: SkString replacement; michael@0: replacement.set("0x"); michael@0: replacement.append(color.c_str() + 1, 2); // add stop colors using given color, turning existing stop color into alpha michael@0: SkASSERT(baseColor.c_str()[0] == '#'); michael@0: SkASSERT(baseColor.size() == 7); michael@0: replacement.append(baseColor.c_str() + 1); michael@0: color.set(replacement); michael@0: } michael@0: translate(parser, true); michael@0: const char* originalPtr = originalColors.c_str(); // restore original gradient values michael@0: for (SkSVGElement** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { michael@0: SkSVGStop* color = (SkSVGStop*) *ptr; michael@0: const char* originalEnd = strchr(originalPtr, ','); michael@0: color->fPaintState.f_stopColor.set(originalPtr, originalEnd - originalPtr); michael@0: originalPtr = originalEnd + 1; michael@0: } michael@0: f_id.set(originalID); michael@0: parser.fSuppressPaint = false; michael@0: parser.fHead = saveHead; michael@0: }