1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawGradient.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkAnimateMaker.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkAnimatorScript.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGradientShader.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if SK_USE_CONDENSED_INFO == 0 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1799547767e9cdabcdae6a575f0f6bfde01d809865rileya@google.comconst SkMemberInfo SkDrawGradient::fInfo[] = { 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_MEMBER_INHERITED, 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_MEMBER_ARRAY(offsets, Float), 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_MEMBER(unitMapper, String) 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2599547767e9cdabcdae6a575f0f6bfde01d809865rileya@google.comDEFINE_GET_MEMBER(SkDrawGradient); 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2783f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.orgSkDrawGradient::SkDrawGradient() { 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3099547767e9cdabcdae6a575f0f6bfde01d809865rileya@google.comSkDrawGradient::~SkDrawGradient() { 31d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com for (int index = 0; index < fDrawColors.count(); index++) 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com delete fDrawColors[index]; 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 351d3c411f5e4d2ad31bc92b3a85957004329ac00dtfarina@chromium.orgbool SkDrawGradient::addChild(SkAnimateMaker& , SkDisplayable* child) { 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(child); 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (child->isColor()) { 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawColor* color = (SkDrawColor*) child; 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *fDrawColors.append() = color; 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4599547767e9cdabcdae6a575f0f6bfde01d809865rileya@google.comint SkDrawGradient::addPrelude() { 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = fDrawColors.count(); 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fColors.setCount(count); 48d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com for (int index = 0; index < count; index++) 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fColors[index] = fDrawColors[index]->color; 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return count; 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DUMP_ENABLED 5499547767e9cdabcdae6a575f0f6bfde01d809865rileya@google.comvoid SkDrawGradient::dumpRest(SkAnimateMaker* maker) { 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dumpAttrs(maker); 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com //can a gradient have no colors? 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool closedYet = false; 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayList::fIndent += 4; 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (SkDrawColor** ptr = fDrawColors.begin(); ptr < fDrawColors.end(); ptr++) { 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (closedYet == false) { 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDebugf(">\n"); 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com closedYet = true; 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawColor* color = *ptr; 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com color->dump(maker); 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 67d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com SkDisplayList::fIndent -= 4; 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dumpChildren(maker, closedYet); //dumps the matrix if it has one 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7299547767e9cdabcdae6a575f0f6bfde01d809865rileya@google.comvoid SkDrawGradient::onEndElement(SkAnimateMaker& maker) { 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (offsets.count() != 0) { 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (offsets.count() != fDrawColors.count()) { 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsDontMatchColors); 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (offsets[0] != 0) { 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustStartWithZero); 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (offsets[offsets.count()-1] != SK_Scalar1) { 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustEndWithOne); 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 1; i < offsets.count(); i++) { 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (offsets[i] <= offsets[i-1]) { 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustIncrease); 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (offsets[i] > SK_Scalar1) { 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustBeNoMoreThanOne); 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com INHERITED::onEndElement(maker); 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if SK_USE_CONDENSED_INFO == 0 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10299547767e9cdabcdae6a575f0f6bfde01d809865rileya@google.comconst SkMemberInfo SkDrawLinearGradient::fInfo[] = { 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_MEMBER_INHERITED, 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_MEMBER_ARRAY(points, Float), 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10999547767e9cdabcdae6a575f0f6bfde01d809865rileya@google.comDEFINE_GET_MEMBER(SkDrawLinearGradient); 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 111d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comSkDrawLinearGradient::SkDrawLinearGradient() { 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11499547767e9cdabcdae6a575f0f6bfde01d809865rileya@google.comvoid SkDrawLinearGradient::onEndElement(SkAnimateMaker& maker) 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (points.count() != 4) 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com maker.setErrorCode(SkDisplayXMLParserError::kGradientPointsLengthMustBeFour); 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com INHERITED::onEndElement(maker); 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DUMP_ENABLED 12299547767e9cdabcdae6a575f0f6bfde01d809865rileya@google.comvoid SkDrawLinearGradient::dump(SkAnimateMaker* maker) { 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dumpBase(maker); 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dumpRest(maker); 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12899547767e9cdabcdae6a575f0f6bfde01d809865rileya@google.comSkShader* SkDrawLinearGradient::getShader() { 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (addPrelude() == 0 || points.count() != 4) 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkShader* shader = SkGradientShader::CreateLinear((SkPoint*)points.begin(), 1329c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org fColors.begin(), offsets.begin(), fColors.count(), (SkShader::TileMode) tileMode, 13383f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org 0, getMatrix()); 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoTDelete<SkShader> autoDel(shader); 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (void)autoDel.detach(); 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return shader; 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if SK_USE_CONDENSED_INFO == 0 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14299547767e9cdabcdae6a575f0f6bfde01d809865rileya@google.comconst SkMemberInfo SkDrawRadialGradient::fInfo[] = { 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_MEMBER_INHERITED, 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_MEMBER(center, Point), 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_MEMBER(radius, Float) 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15099547767e9cdabcdae6a575f0f6bfde01d809865rileya@google.comDEFINE_GET_MEMBER(SkDrawRadialGradient); 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 152d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comSkDrawRadialGradient::SkDrawRadialGradient() : radius(0) { 153d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com center.set(0, 0); 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DUMP_ENABLED 15799547767e9cdabcdae6a575f0f6bfde01d809865rileya@google.comvoid SkDrawRadialGradient::dump(SkAnimateMaker* maker) { 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dumpBase(maker); 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dumpRest(maker); 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16399547767e9cdabcdae6a575f0f6bfde01d809865rileya@google.comSkShader* SkDrawRadialGradient::getShader() { 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (addPrelude() == 0) 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkShader* shader = SkGradientShader::CreateRadial(center, 1679c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org radius, fColors.begin(), offsets.begin(), fColors.count(), (SkShader::TileMode) tileMode, 16883f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org 0, getMatrix()); 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoTDelete<SkShader> autoDel(shader); 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (void)autoDel.detach(); 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return shader; 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 173