145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com#include <ctype.h> 245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com#include "SkPath.h" 345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com#include "SkParse.h" 445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com#include "SkPoint.h" 545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com#include "SkUtils.h" 645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com#define QUADRATIC_APPROXIMATION 0 745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comconst char logoStr[] = 945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "<path fill=\"#0081C6\"" 1045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "d=\"M440.51,289.479c1.623,1.342,5.01,4.164,5.01,9.531c0,5.223-2.965,7.697-5.93,10.024" 1145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c-0.918,0.916-1.977,1.907-1.977,3.462c0,1.551,1.059,2.397,1.834,3.035l2.545,1.973c3.105,2.613,5.928,5.016,5.928,9.889" 1245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c0,6.635-6.426,13.341-18.566,13.341c-10.238,0-15.178-4.87-15.178-10.097c0-2.543,1.268-6.139,5.438-8.613" 1345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c4.373-2.682,10.307-3.033,13.482-3.249c-0.99-1.271-2.119-2.61-2.119-4.798c0-1.199,0.355-1.907,0.707-2.754" 1445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c-0.779,0.07-1.553,0.141-2.26,0.141c-7.482,0-11.719-5.579-11.719-11.082c0-3.247,1.484-6.851,4.518-9.461" 1545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c4.025-3.318,8.824-3.883,12.639-3.883h14.541l-4.518,2.541H440.51z" 1645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "M435.494,320.826c-0.562-0.072-0.916-0.072-1.619-0.072" 1745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c-0.637,0-4.451,0.143-7.416,1.132c-1.553,0.564-6.07,2.257-6.07,7.271c0,5.013,4.873,8.615,12.426,8.615" 1845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c6.775,0,10.379-3.253,10.379-7.624C443.193,326.54,440.863,324.64,435.494,320.826z" 1945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "M437.543,307.412" 2045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c1.623-1.627,1.764-3.883,1.764-5.154c0-5.083-3.035-12.99-8.893-12.99c-1.838,0-3.812,0.918-4.945,2.331" 2145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c-1.199,1.483-1.551,3.387-1.551,5.225c0,4.729,2.754,12.565,8.826,12.565C434.508,309.389,436.41,308.543,437.543,307.412z\"/>" 2245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "<path fill=\"#FFD200\"" 2345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "d=\"M396.064,319.696c-11.206,0-17.198-8.739-17.198-16.636c0-9.233,7.542-17.126,18.258-17.126" 2445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c10.357,0,16.844,8.104,16.844,16.635C413.969,310.884,407.557,319.696,396.064,319.696z" 2545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "M404.873,313.987" 2645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c1.695-2.257,2.119-5.074,2.119-7.826c0-6.202-2.961-18.042-11.701-18.042c-2.326,0-4.652,0.918-6.342,2.399" 2745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c-2.749,2.465-3.245,5.566-3.245,8.599c0,6.977,3.454,18.463,11.984,18.463C400.436,317.58,403.256,316.242,404.873,313.987z\"/>" 2845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "<path fill=\"#ED174F\"" 2945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "d=\"M357.861,319.696c-11.207,0-17.199-8.739-17.199-16.636c0-9.233,7.544-17.126,18.258-17.126" 3045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c10.359,0,16.845,8.104,16.845,16.635C375.764,310.884,369.351,319.696,357.861,319.696z" 3145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "M366.671,313.987" 3245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c1.693-2.257,2.116-5.074,2.116-7.826c0-6.202-2.961-18.042-11.701-18.042c-2.325,0-4.652,0.918-6.344,2.399" 3345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c-2.749,2.465-3.241,5.566-3.241,8.599c0,6.977,3.452,18.463,11.983,18.463C362.234,317.58,365.053,316.242,366.671,313.987z\"/>" 3445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "<path fill=\"#0081C6\"" 3545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "d=\"M335.278,318.591l-10.135,2.339c-4.111,0.638-7.795,1.204-11.69,1.204" 3645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c-19.56,0-26.998-14.386-26.998-25.654c0-13.746,10.558-26.498,28.629-26.498c3.827,0,7.51,0.564,10.839,1.486" 3745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c5.316,1.488,7.796,3.331,9.355,4.394l-5.883,5.599l-2.479,0.565l1.771-2.837c-2.408-2.336-6.805-6.658-15.164-6.658" 3845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c-11.196,0-19.63,8.507-19.63,20.906c0,13.319,9.638,25.861,25.084,25.861c4.539,0,6.874-0.918,9-1.771v-11.407l-10.698,0.566" 3945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "l5.667-3.047h15.023l-1.841,1.77c-0.5,0.424-0.567,0.57-0.71,1.133c-0.073,0.64-0.141,2.695-0.141,3.403V318.591z\"/>" 4045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "<path fill=\"#49A942\"" 4145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "d=\"M462.908,316.552c-2.342-0.214-2.832-0.638-2.832-3.401v-0.782v-39.327c0.014-0.153,0.025-0.31,0.041-0.457" 4245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c0.283-2.479,0.992-2.903,3.189-4.182h-10.135l-5.316,2.552h5.418v0.032l-0.004-0.024v41.406v2.341" 4345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c0,1.416-0.281,1.629-1.912,3.753H463.9l2.623-1.557C465.318,316.763,464.113,316.692,462.908,316.552z\"/>" 4445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "<path fill=\"#ED174F\"" 4545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "d=\"M491.742,317.203c-0.771,0.422-1.547,0.916-2.318,1.268c-2.326,1.055-4.719,1.336-6.83,1.336" 4645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c-2.25,0-5.77-0.143-9.361-2.744c-4.992-3.521-7.176-9.572-7.176-14.851c0-10.906,8.869-16.255,16.115-16.255" 4745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c2.533,0,5.141,0.633,7.252,1.972c3.516,2.318,4.43,5.344,4.922,6.963l-16.535,6.688l-5.422,0.422" 4845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c1.758,8.938,7.812,14.145,14.498,14.145c3.59,0,6.193-1.266,8.586-2.461L491.742,317.203z" 4945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "M485.129,296.229" 5045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c1.336-0.493,2.039-0.914,2.039-1.899c0-2.812-3.166-6.053-6.967-6.053c-2.818,0-8.094,2.183-8.094,9.783" 5145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "c0,1.197,0.141,2.464,0.213,3.73L485.129,296.229z\"/>" 5245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "<path fill=\"#77787B\"" 5345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "d=\"M498.535,286.439v4.643h-0.564v-4.643h-1.537v-0.482h3.637v0.482H498.535z\"/>" 5445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "<path fill=\"#77787B\"" 5545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "d=\"M504.863,291.082v-4.687h-0.023l-1.432,4.687h-0.439l-1.443-4.687h-0.02v4.687h-0.512v-5.125h0.877" 5645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com "l1.307,4.143h0.018l1.285-4.143h0.891v5.125H504.863z\"/>" 5745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com; 5845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 5945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comsize_t logoStrLen = sizeof(logoStr); 6045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 6145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com#if QUADRATIC_APPROXIMATION 6245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com//////////////////////////////////////////////////////////////////////////////////// 6345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com//functions to approximate a cubic using two quadratics 6445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 6545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com// midPt sets the first argument to be the midpoint of the other two 6645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com// it is used by quadApprox 6745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comstatic inline void midPt(SkPoint& dest,const SkPoint& a,const SkPoint& b) 6845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com{ 6945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com dest.set(SkScalarAve(a.fX, b.fX),SkScalarAve(a.fY, b.fY)); 7045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com} 7145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com// quadApprox - makes an approximation, which we hope is faster 7245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comstatic void quadApprox(SkPath &fPath, const SkPoint &p0, const SkPoint &p1, const SkPoint &p2) 7345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com{ 7445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com //divide the cubic up into two cubics, then convert them into quadratics 7545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com //define our points 7645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkPoint c,j,k,l,m,n,o,p,q, mid; 7745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com fPath.getLastPt(&c); 7845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com midPt(j, p0, c); 7945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com midPt(k, p0, p1); 8045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com midPt(l, p1, p2); 8145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com midPt(o, j, k); 8245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com midPt(p, k, l); 8345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com midPt(q, o, p); 8445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com //compute the first half 8545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com m.set(SkScalarHalf(3*j.fX - c.fX), SkScalarHalf(3*j.fY - c.fY)); 8645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com n.set(SkScalarHalf(3*o.fX -q.fX), SkScalarHalf(3*o.fY - q.fY)); 8745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com midPt(mid,m,n); 8845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com fPath.quadTo(mid,q); 8945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com c = q; 9045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com //compute the second half 9145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com m.set(SkScalarHalf(3*p.fX - c.fX), SkScalarHalf(3*p.fY - c.fY)); 9245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com n.set(SkScalarHalf(3*l.fX -p2.fX),SkScalarHalf(3*l.fY -p2.fY)); 9345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com midPt(mid,m,n); 9445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com fPath.quadTo(mid,p2); 9545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com} 9645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com#endif 9745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 9845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 9945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comstatic inline bool is_between(int c, int min, int max) 10045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com{ 10145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com return (unsigned)(c - min) <= (unsigned)(max - min); 10245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com} 10345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 10445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comstatic inline bool is_ws(int c) 10545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com{ 10645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com return is_between(c, 1, 32); 10745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com} 10845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 10945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comstatic inline bool is_digit(int c) 11045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com{ 11145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com return is_between(c, '0', '9'); 11245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com} 11345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 11445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comstatic inline bool is_sep(int c) 11545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com{ 11645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com return is_ws(c) || c == ','; 11745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com} 11845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 11945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comstatic const char* skip_ws(const char str[]) 12045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com{ 12145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkASSERT(str); 12245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com while (is_ws(*str)) 12345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com str++; 12445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com return str; 12545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com} 12645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 12745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comstatic const char* skip_sep(const char str[]) 12845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com{ 12945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkASSERT(str); 13045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com while (is_sep(*str)) 13145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com str++; 13245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com return str; 13345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com} 13445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 13545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comstatic const char* find_points(const char str[], SkPoint value[], int count, 13645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com bool isRelative, SkPoint* relative) 13745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com{ 13845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com str = SkParse::FindScalars(str, &value[0].fX, count * 2); 13945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com if (isRelative) { 14045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com for (int index = 0; index < count; index++) { 14145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com value[index].fX += relative->fX; 14245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com value[index].fY += relative->fY; 14345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 14445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 14545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com return str; 14645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com} 14745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 14845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comstatic const char* find_scalar(const char str[], SkScalar* value, 14945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com bool isRelative, SkScalar relative) 15045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com{ 15145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com str = SkParse::FindScalar(str, value); 15245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com if (isRelative) 15345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com *value += relative; 15445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com return str; 15545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com} 15645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 15745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comstatic void showPathContour(SkPath::Iter& iter) { 15845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com uint8_t verb; 15945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkPoint pts[4]; 16045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 16145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com switch (verb) { 16245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com case SkPath::kMove_Verb: 16345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkDebugf("path.moveTo(%1.9gf,%1.9gf);\n", pts[0].fX, pts[0].fY); 16445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com continue; 16545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com case SkPath::kLine_Verb: 16645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkDebugf("path.lineTo(%1.9gf,%1.9gf);\n", pts[1].fX, pts[1].fY); 16745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com break; 16845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com case SkPath::kQuad_Verb: 16945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkDebugf("path.quadTo(%1.9gf,%1.9gf, %1.9gf,%1.9gf);\n", 17045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY); 17145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com break; 17245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com case SkPath::kCubic_Verb: 17345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkDebugf("path.cubicTo(%1.9gf,%1.9gf, %1.9gf,%1.9gf, %1.9gf,%1.9gf);\n", 17445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY, pts[3].fX, pts[3].fY); 17545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com break; 17645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com case SkPath::kClose_Verb: 17745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkDebugf("path.close();\n"); 17845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com break; 17945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com default: 18045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkDEBUGFAIL("bad verb"); 18145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com return; 18245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 18345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 18445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com} 18545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 18645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comstatic void showPath(const SkPath& path) { 18745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkPath::Iter iter(path, true); 18845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com int rectCount = path.isRectContours() ? path.rectContours(NULL, NULL) : 0; 18945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com if (rectCount > 0) { 19045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkTDArray<SkRect> rects; 19145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkTDArray<SkPath::Direction> directions; 19245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com rects.setCount(rectCount); 19345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com directions.setCount(rectCount); 19445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com path.rectContours(rects.begin(), directions.begin()); 19545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com for (int contour = 0; contour < rectCount; ++contour) { 19645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com const SkRect& rect = rects[contour]; 19745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkDebugf("path.addRect(%1.9g, %1.9g, %1.9g, %1.9g, %s);\n", rect.fLeft, rect.fTop, 19845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com rect.fRight, rect.fBottom, directions[contour] == SkPath::kCCW_Direction 19945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com ? "SkPath::kCCW_Direction" : "SkPath::kCW_Direction"); 20045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 20145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com return; 20245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 20345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com iter.setPath(path, true); 20445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com showPathContour(iter); 20545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com} 20645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 20745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comstatic const char* parsePath(const char* data) { 20845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkPath fPath; 20945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkPoint f = {0, 0}; 21045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkPoint c = {0, 0}; 21145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkPoint lastc = {0, 0}; 21245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkPoint points[3]; 21345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com char op = '\0'; 21445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com char previousOp = '\0'; 21545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com bool relative = false; 21645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com do { 21745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com data = skip_ws(data); 21845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com if (data[0] == '\0') 21945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com break; 22045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com char ch = data[0]; 22145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com if (is_digit(ch) || ch == '-' || ch == '+') { 22245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com if (op == '\0') { 22345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkASSERT(0); 22445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com return 0; 22545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 22645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 22745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com else { 22845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com op = ch; 22945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com relative = false; 23045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com if (islower(op)) { 23145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com op = (char) toupper(op); 23245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com relative = true; 23345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 23445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com data++; 23545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com data = skip_sep(data); 23645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 23745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com switch (op) { 23845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com case 'M': 23945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com data = find_points(data, points, 1, relative, &c); 24045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com fPath.moveTo(points[0]); 24145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com op = 'L'; 24245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com c = points[0]; 24345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com break; 24445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com case 'L': 24545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com data = find_points(data, points, 1, relative, &c); 24645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com fPath.lineTo(points[0]); 24745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com c = points[0]; 24845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com break; 24945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com case 'H': { 25045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkScalar x; 25145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com data = find_scalar(data, &x, relative, c.fX); 25245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com fPath.lineTo(x, c.fY); 25345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com c.fX = x; 25445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 25545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com break; 25645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com case 'V': { 25745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkScalar y; 25845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com data = find_scalar(data, &y, relative, c.fY); 25945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com fPath.lineTo(c.fX, y); 26045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com c.fY = y; 26145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 26245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com break; 26345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com case 'C': 26445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com data = find_points(data, points, 3, relative, &c); 26545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com goto cubicCommon; 26645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com case 'S': 26745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com data = find_points(data, &points[1], 2, relative, &c); 26845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com points[0] = c; 26945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com if (previousOp == 'C' || previousOp == 'S') { 27045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com points[0].fX -= lastc.fX - c.fX; 27145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com points[0].fY -= lastc.fY - c.fY; 27245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 27345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com cubicCommon: 27445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com // if (data[0] == '\0') 27545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com // return; 27645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com#if QUADRATIC_APPROXIMATION 27745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com quadApprox(fPath, points[0], points[1], points[2]); 27845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com#else //this way just does a boring, slow old cubic 27945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com fPath.cubicTo(points[0], points[1], points[2]); 28045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com#endif 28145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com //if we are using the quadApprox, lastc is what it would have been if we had used 28245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com //cubicTo 28345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com lastc = points[1]; 28445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com c = points[2]; 28545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com break; 28645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com case 'Q': // Quadratic Bezier Curve 28745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com data = find_points(data, points, 2, relative, &c); 28845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com goto quadraticCommon; 28945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com case 'T': 29045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com data = find_points(data, &points[1], 1, relative, &c); 29145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com points[0] = points[1]; 29245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com if (previousOp == 'Q' || previousOp == 'T') { 29345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com points[0].fX = c.fX * 2 - lastc.fX; 29445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com points[0].fY = c.fY * 2 - lastc.fY; 29545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 29645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com quadraticCommon: 29745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com fPath.quadTo(points[0], points[1]); 29845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com lastc = points[0]; 29945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com c = points[1]; 30045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com break; 30145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com case 'Z': 30245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com fPath.close(); 30345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com#if 0 // !!! still a bug? 30445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com if (fPath.isEmpty() && (f.fX != 0 || f.fY != 0)) { 30545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com c.fX -= SkScalar.Epsilon; // !!! enough? 30645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com fPath.moveTo(c); 30745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com fPath.lineTo(f); 30845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com fPath.close(); 30945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 31045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com#endif 31145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com c = f; 31245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com op = '\0'; 31345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com break; 31445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com case '~': { 31545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkPoint args[2]; 31645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com data = find_points(data, args, 2, false, NULL); 31745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com fPath.moveTo(args[0].fX, args[0].fY); 31845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com fPath.lineTo(args[1].fX, args[1].fY); 31945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 32045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com break; 32145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com default: 32245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkASSERT(0); 32345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com return 0; 32445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 32545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com if (previousOp == 0) 32645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com f = c; 32745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com previousOp = op; 32845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } while (data[0] != '"'); 32945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com showPath(fPath); 33045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com return data; 33145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com} 33245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 33345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comconst char pathPrefix[] = "<path fill=\""; 33445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com 33545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comvoid parseSVG(); 33645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.comvoid parseSVG() { 33745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com const char* data = logoStr; 33845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com const char* dataEnd = logoStr + logoStrLen - 1; 33945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com while (data < dataEnd) { 34045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkASSERT(strncmp(data, pathPrefix, sizeof(pathPrefix) - 1) == 0); 34145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com data += sizeof(pathPrefix) - 1; 34245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkDebugf("paint.setColor(0xFF%c%c%c%c%c%c);\n", data[1], data[2], data[3], data[4], 34345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com data[5], data[6]); 34445a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com data += 8; 34545a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkASSERT(strncmp(data, "d=\"", 3) == 0); 34645a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com data += 3; 34745a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkDebugf("path.reset();\n"); 34845a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com data = parsePath(data); 34945a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkDebugf("canvas->drawPath(path, paint);\n"); 35045a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com SkASSERT(strncmp(data, "\"/>", 3) == 0); 35145a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com data += 3; 35245a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com } 35345a8fc6a8b00451f807783f2a6ec640e9bcc7256caryclark@google.com} 354