1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 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 */ 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkParsePaint.h" 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTSearch.h" 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkParse.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkImageDecoder.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGradientShader.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkShader* inflate_shader(const SkDOM& dom, const SkDOM::Node* node) 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 16d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com if ((node = dom.getFirstChild(node, "shader")) == NULL) 17d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com return NULL; 18d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 19d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com const char* str; 20d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 21d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com if (dom.hasAttr(node, "type", "linear-gradient")) 22d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com { 23d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com SkColor colors[2]; 24d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com SkPoint pts[2]; 25d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 26d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com colors[0] = colors[1] = SK_ColorBLACK; // need to initialized the alpha to opaque, since FindColor doesn't set it 27d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com if ((str = dom.findAttr(node, "c0")) != NULL && 28d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com SkParse::FindColor(str, &colors[0]) && 29d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com (str = dom.findAttr(node, "c1")) != NULL && 30d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com SkParse::FindColor(str, &colors[1]) && 31d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com dom.findScalars(node, "p0", &pts[0].fX, 2) && 32d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com dom.findScalars(node, "p1", &pts[1].fX, 2)) 33d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com { 34d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com SkShader::TileMode mode = SkShader::kClamp_TileMode; 35d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com int index; 36d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 37d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com if ((index = dom.findList(node, "tile-mode", "clamp,repeat,mirror")) >= 0) 38d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com mode = (SkShader::TileMode)index; 39d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com return SkGradientShader::CreateLinear(pts, colors, NULL, 2, mode); 40d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com } 41d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com } 42d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com else if (dom.hasAttr(node, "type", "bitmap")) 43d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com { 44d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com if ((str = dom.findAttr(node, "src")) == NULL) 45d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com return NULL; 46d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 47d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com SkBitmap bm; 48d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 49d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com if (SkImageDecoder::DecodeFile(str, &bm)) 50d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com { 51d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com SkShader::TileMode mode = SkShader::kRepeat_TileMode; 52d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com int index; 53d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 54d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com if ((index = dom.findList(node, "tile-mode", "clamp,repeat,mirror")) >= 0) 55d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com mode = (SkShader::TileMode)index; 56d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 57d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com return SkShader::CreateBitmapShader(bm, mode, mode); 58d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com } 59d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com } 60d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com return NULL; 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPaint_Inflate(SkPaint* paint, const SkDOM& dom, const SkDOM::Node* node) 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 65d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com SkASSERT(paint); 66d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com SkASSERT(&dom); 67d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com SkASSERT(node); 68d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 69d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com SkScalar x; 70d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 71d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com if (dom.findScalar(node, "stroke-width", &x)) 72d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com paint->setStrokeWidth(x); 73d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com if (dom.findScalar(node, "text-size", &x)) 74d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com paint->setTextSize(x); 75d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 76d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com bool b; 77d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 78d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com SkASSERT("legacy: use is-stroke" && !dom.findBool(node, "is-frame", &b)); 79d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 80d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com if (dom.findBool(node, "is-stroke", &b)) 81d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com paint->setStyle(b ? SkPaint::kStroke_Style : SkPaint::kFill_Style); 82d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com if (dom.findBool(node, "is-antialias", &b)) 83d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com paint->setAntiAlias(b); 84d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com if (dom.findBool(node, "is-lineartext", &b)) 85d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com paint->setLinearText(b); 86d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 87d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com const char* str = dom.findAttr(node, "color"); 88d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com if (str) 89d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com { 90d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com SkColor c = paint->getColor(); 91d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com if (SkParse::FindColor(str, &c)) 92d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com paint->setColor(c); 93d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com } 94d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 95d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com // do this AFTER parsing for the color 96d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com if (dom.findScalar(node, "opacity", &x)) 97d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com { 98d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com x = SkMaxScalar(0, SkMinScalar(x, SK_Scalar1)); 99e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com paint->setAlpha(SkScalarRoundToInt(x * 255)); 100d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com } 101d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 102d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com int index = dom.findList(node, "text-anchor", "left,center,right"); 103d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com if (index >= 0) 104d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com paint->setTextAlign((SkPaint::Align)index); 105d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 106d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com SkShader* shader = inflate_shader(dom, node); 107d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com if (shader) 108d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com paint->setShader(shader)->unref(); 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 110