|  | 
 | /* | 
 |  * Copyright 2006 The Android Open Source Project | 
 |  * | 
 |  * Use of this source code is governed by a BSD-style license that can be | 
 |  * found in the LICENSE file. | 
 |  */ | 
 |  | 
 |  | 
 | #include "SkDrawGradient.h" | 
 | #include "SkAnimateMaker.h" | 
 | #include "SkAnimatorScript.h" | 
 | #include "SkGradientShader.h" | 
 |  | 
 | #if SK_USE_CONDENSED_INFO == 0 | 
 |  | 
 | const SkMemberInfo SkDrawGradient::fInfo[] = { | 
 |     SK_MEMBER_INHERITED, | 
 |     SK_MEMBER_ARRAY(offsets, Float), | 
 |     SK_MEMBER(unitMapper, String) | 
 | }; | 
 |  | 
 | #endif | 
 |  | 
 | DEFINE_GET_MEMBER(SkDrawGradient); | 
 |  | 
 | SkDrawGradient::SkDrawGradient() { | 
 | } | 
 |  | 
 | SkDrawGradient::~SkDrawGradient() { | 
 |     for (int index = 0; index < fDrawColors.count(); index++) | 
 |         delete fDrawColors[index]; | 
 | } | 
 |  | 
 | bool SkDrawGradient::addChild(SkAnimateMaker& , SkDisplayable* child) { | 
 |     SkASSERT(child); | 
 |     if (child->isColor()) { | 
 |         SkDrawColor* color = (SkDrawColor*) child; | 
 |         *fDrawColors.append() = color; | 
 |         return true; | 
 |     } | 
 |     return false; | 
 | } | 
 |  | 
 | int SkDrawGradient::addPrelude() { | 
 |     int count = fDrawColors.count(); | 
 |     fColors.setCount(count); | 
 |     for (int index = 0; index < count; index++) | 
 |         fColors[index] = fDrawColors[index]->color; | 
 |     return count; | 
 | } | 
 |  | 
 | #ifdef SK_DUMP_ENABLED | 
 | void SkDrawGradient::dumpRest(SkAnimateMaker* maker) { | 
 |     dumpAttrs(maker); | 
 |     //can a gradient have no colors? | 
 |     bool closedYet = false; | 
 |     SkDisplayList::fIndent += 4; | 
 |     for (SkDrawColor** ptr = fDrawColors.begin(); ptr < fDrawColors.end(); ptr++) { | 
 |         if (closedYet == false) { | 
 |             SkDebugf(">\n"); | 
 |             closedYet = true; | 
 |         } | 
 |         SkDrawColor* color = *ptr; | 
 |         color->dump(maker); | 
 |     } | 
 |     SkDisplayList::fIndent -= 4; | 
 |     dumpChildren(maker, closedYet); //dumps the matrix if it has one | 
 | } | 
 | #endif | 
 |  | 
 | void SkDrawGradient::onEndElement(SkAnimateMaker& maker) { | 
 |     if (offsets.count() != 0) { | 
 |         if (offsets.count() != fDrawColors.count()) { | 
 |             maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsDontMatchColors); | 
 |             return; | 
 |         } | 
 |         if (offsets[0] != 0) { | 
 |             maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustStartWithZero); | 
 |             return; | 
 |         } | 
 |         if (offsets[offsets.count()-1] != SK_Scalar1) { | 
 |             maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustEndWithOne); | 
 |             return; | 
 |         } | 
 |         for (int i = 1; i < offsets.count(); i++) { | 
 |             if (offsets[i] <= offsets[i-1]) { | 
 |                 maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustIncrease); | 
 |                 return; | 
 |             } | 
 |             if (offsets[i] > SK_Scalar1) { | 
 |                 maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustBeNoMoreThanOne); | 
 |                 return; | 
 |             } | 
 |         } | 
 |     } | 
 |     INHERITED::onEndElement(maker); | 
 | } | 
 |  | 
 | #if SK_USE_CONDENSED_INFO == 0 | 
 |  | 
 | const SkMemberInfo SkDrawLinearGradient::fInfo[] = { | 
 |     SK_MEMBER_INHERITED, | 
 |     SK_MEMBER_ARRAY(points, Float), | 
 | }; | 
 |  | 
 | #endif | 
 |  | 
 | DEFINE_GET_MEMBER(SkDrawLinearGradient); | 
 |  | 
 | SkDrawLinearGradient::SkDrawLinearGradient() { | 
 | } | 
 |  | 
 | void SkDrawLinearGradient::onEndElement(SkAnimateMaker& maker) | 
 | { | 
 |     if (points.count() != 4) | 
 |         maker.setErrorCode(SkDisplayXMLParserError::kGradientPointsLengthMustBeFour); | 
 |     INHERITED::onEndElement(maker); | 
 | } | 
 |  | 
 | #ifdef SK_DUMP_ENABLED | 
 | void SkDrawLinearGradient::dump(SkAnimateMaker* maker) { | 
 |     dumpBase(maker); | 
 |     dumpRest(maker); | 
 |     } | 
 | #endif | 
 |  | 
 | SkShader* SkDrawLinearGradient::getShader() { | 
 |     if (addPrelude() == 0 || points.count() != 4) | 
 |         return NULL; | 
 |     SkShader* shader = SkGradientShader::CreateLinear((SkPoint*)points.begin(), | 
 |         fColors.begin(), offsets.begin(), fColors.count(), (SkShader::TileMode) tileMode, | 
 |         0, getMatrix()); | 
 |     SkAutoTDelete<SkShader> autoDel(shader); | 
 |     (void)autoDel.detach(); | 
 |     return shader; | 
 | } | 
 |  | 
 |  | 
 | #if SK_USE_CONDENSED_INFO == 0 | 
 |  | 
 | const SkMemberInfo SkDrawRadialGradient::fInfo[] = { | 
 |     SK_MEMBER_INHERITED, | 
 |     SK_MEMBER(center, Point), | 
 |     SK_MEMBER(radius, Float) | 
 | }; | 
 |  | 
 | #endif | 
 |  | 
 | DEFINE_GET_MEMBER(SkDrawRadialGradient); | 
 |  | 
 | SkDrawRadialGradient::SkDrawRadialGradient() : radius(0) { | 
 |     center.set(0, 0); | 
 | } | 
 |  | 
 | #ifdef SK_DUMP_ENABLED | 
 | void SkDrawRadialGradient::dump(SkAnimateMaker* maker) { | 
 |     dumpBase(maker); | 
 |     dumpRest(maker); | 
 | } | 
 | #endif | 
 |  | 
 | SkShader* SkDrawRadialGradient::getShader() { | 
 |     if (addPrelude() == 0) | 
 |         return NULL; | 
 |     SkShader* shader = SkGradientShader::CreateRadial(center, | 
 |         radius, fColors.begin(), offsets.begin(), fColors.count(), (SkShader::TileMode) tileMode, | 
 |         0, getMatrix()); | 
 |     SkAutoTDelete<SkShader> autoDel(shader); | 
 |     (void)autoDel.detach(); | 
 |     return shader; | 
 | } |