blob: b56ca3ae0988e8345577f4feac1727c48a7f3084 [file] [log] [blame]
static constexpr char SKSL_MINIFIED_sksl_graphite_vert[] =
"const float $PI=3.14159274;const float $kDegree=3.;const float $kPrecision="
"4.;const float $kLengthTerm=3.;const float $kLengthTermPow2=9.;$pure float $wangs_formula_max_fdiff_p2"
"(float2 p0,float2 p1,float2 p2,float2 p3,float2x2 matrix){float2 d0=matrix*"
"(fma(float2(-2.),p1,p2)+p0);float2 d1=matrix*(fma(float2(-2.),p2,p3)+p1);return"
" max(dot(d0,d0),dot(d1,d1));}$pure float $wangs_formula_cubic(float2 p0,float2"
" p1,float2 p2,float2 p3,float2x2 matrix){float m=$wangs_formula_max_fdiff_p2"
"(p0,p1,p2,p3,matrix);return max(ceil(sqrt($kLengthTerm*sqrt(m))),1.);}$pure"
" float $wangs_formula_cubic_log2(float2 p0,float2 p1,float2 p2,float2 p3,float2x2"
" matrix){float m=$wangs_formula_max_fdiff_p2(p0,p1,p2,p3,matrix);return ceil"
"(log2(max($kLengthTermPow2*m,1.))*.25);}$pure float $wangs_formula_conic_p2"
"(float2 p0,float2 p1,float2 p2,float w){float2 C=(min(min(p0,p1),p2)+max(max"
"(p0,p1),p2))*.5;p0-=C;p1-=C;p2-=C;float m=sqrt(max(max(dot(p0,p0),dot(p1,p1"
")),dot(p2,p2)));float2 dp=fma(float2(-2.*w),p1,p0)+p2;float dw=abs(fma(-2.,"
"w,2.));float rp_minus_1=max(0.,fma(m,$kPrecision,-1.));float numer=length(dp"
")*$kPrecision+rp_minus_1*dw;float denom=4.*min(w,1.);return numer/denom;}$pure"
" float $wangs_formula_conic(float2 p0,float2 p1,float2 p2,float w){float n2"
"=$wangs_formula_conic_p2(p0,p1,p2,w);return max(ceil(sqrt(n2)),1.);}$pure float"
" $wangs_formula_conic_log2(float2 p0,float2 p1,float2 p2,float w){float n2="
"$wangs_formula_conic_p2(p0,p1,p2,w);return ceil(log2(max(n2,1.))*.5);}$pure"
" float2 $robust_normalize_diff(float2 a,float2 b){float2 diff=a-b;if(diff=="
"float2(0.)){return float2(0.);}else{float invMag=1./max(abs(diff.x),abs(diff"
".y));return normalize(invMag*diff);}}$pure float $cosine_between_unit_vectors"
"(float2 a,float2 b){return clamp(dot(a,b),-1.,1.);}$pure float $miter_extent"
"(float cosTheta,float miterLimit){float x=fma(cosTheta,.5,.5);return(x*miterLimit"
")*miterLimit>=1.?inversesqrt(x):sqrt(x);}$pure float $num_radial_segments_per_radian"
"(float approxDevStrokeRadius){return.5/acos(max(1.-.25/approxDevStrokeRadius"
",-1.));}$pure float $unchecked_mix(float a,float b,float T){return fma(b-a,"
"T,a);}$pure float2 $unchecked_mix(float2 a,float2 b,float T){return fma(b-a"
",float2(T),a);}$pure float4 $unchecked_mix(float4 a,float4 b,float4 T){return"
" fma(b-a,T,a);}$pure float2 tessellate_filled_curve(float2x2 vectorXform,float"
" resolveLevel,float idxInResolveLevel,float4 p01,float4 p23){float2 localcoord"
";if(isinf(p23.z)){localcoord=resolveLevel!=0.?p01.zw:(idxInResolveLevel!=0."
"?p23.xy:p01.xy);}else{float2 p0=p01.xy;float2 p1=p01.zw;float2 p2=p23.xy;float2"
" p3=p23.zw;float w=-1.;float maxResolveLevel;if(isinf(p23.w)){w=p3.x;maxResolveLevel"
"=$wangs_formula_conic_log2(vectorXform*p0,vectorXform*p1,vectorXform*p2,w);"
"p1*=w;p3=p2;}else{maxResolveLevel=$wangs_formula_cubic_log2(p0,p1,p2,p3,vectorXform"
");}if(resolveLevel>maxResolveLevel){idxInResolveLevel=floor(ldexp(idxInResolveLevel"
",int(maxResolveLevel-resolveLevel)));resolveLevel=maxResolveLevel;}float fixedVertexID"
"=floor(.5+ldexp(idxInResolveLevel,int(5.-resolveLevel)));if(0.<fixedVertexID"
"&&fixedVertexID<32.){float T=fixedVertexID*.03125;float2 ab=mix(p0,p1,T);float2"
" bc=mix(p1,p2,T);float2 cd=mix(p2,p3,T);float2 abc=mix(ab,bc,T);float2 bcd="
"mix(bc,cd,T);float2 abcd=mix(abc,bcd,T);float u=mix(1.,w,T);float v=(w+1.)-"
"u;float uv=mix(u,v,T);localcoord=w<0.?abcd:abc/uv;}else{localcoord=fixedVertexID"
"==0.?p0:p3;}}return localcoord;}$pure float4 tessellate_stroked_curve(float"
" edgeID,float maxEdges,float2x2 affineMatrix,float2 translate,float maxScale"
",float4 p01,float4 p23,float2 lastControlPoint,float2 strokeParams){float2 p0"
"=p01.xy;float2 p1=p01.zw;float2 p2=p23.xy;float2 p3=p23.zw;float w=-1.;if(isinf"
"(p23.w)){w=p3.x;p3=p2;}float numParametricSegments;if(w<0.){if(p0==p1&&p2=="
"p3){numParametricSegments=1.;}else{numParametricSegments=$wangs_formula_cubic"
"(p0,p1,p2,p3,affineMatrix);}}else{numParametricSegments=$wangs_formula_conic"
"(affineMatrix*p0,affineMatrix*p1,affineMatrix*p2,w);}float strokeRadius=strokeParams"
".x;float joinType=strokeParams.y;bool isHairline=strokeParams.x==0.;float numRadialSegmentsPerRadian"
";if(isHairline){numRadialSegmentsPerRadian=$num_radial_segments_per_radian("
"1.);strokeRadius=.5;}else{numRadialSegmentsPerRadian=$num_radial_segments_per_radian"
"(maxScale*strokeParams.x);}if(isHairline){p0=affineMatrix*p0;p1=affineMatrix"
"*p1;p2=affineMatrix*p2;p3=affineMatrix*p3;lastControlPoint=affineMatrix*lastControlPoint"
";}float2 tan0=$robust_normalize_diff(p0==p1?(p1==p2?p3:p2):p1,p0);float2 tan1"
"=$robust_normalize_diff(p3,p3==p2?(p2==p1?p0:p1):p2);if(tan0==float2(0.)){tan0"
"=float2(1.,0.);tan1=float2(-1.,0.);}float numEdgesInJoin;if(joinType>=0.){numEdgesInJoin"
"=(sign(joinType)+1.)+2.;}else{float2 prevTan=$robust_normalize_diff(p0,lastControlPoint"
");float joinRads=acos($cosine_between_unit_vectors(prevTan,tan0));float numRadialSegmentsInJoin"
"=max(ceil(joinRads*numRadialSegmentsPerRadian),1.);numEdgesInJoin=numRadialSegmentsInJoin"
"+2.;numEdgesInJoin=min(numEdgesInJoin,maxEdges-2.);}float turn=cross_length_2d"
"(p2-p0,p3-p1);float combinedEdgeID=abs(edgeID)-numEdgesInJoin;if(combinedEdgeID"
"<0.){tan1=tan0;if(lastControlPoint!=p0){tan0=$robust_normalize_diff(p0,lastControlPoint"
");}turn=cross_length_2d(tan0,tan1);}float cosTheta=$cosine_between_unit_vectors"
"(tan0,tan1);float rotation=acos(cosTheta);if(turn<0.){rotation=-rotation;}float"
" numRadialSegments;float strokeOutset=sign(edgeID);if(combinedEdgeID<0.){numRadialSegments"
"=numEdgesInJoin-2.;numParametricSegments=1.;p3=(p2=(p1=p0));combinedEdgeID+="
"numRadialSegments+1.;float sinEpsilon=.01;bool tangentsNearlyParallel=abs(turn"
")*inversesqrt(dot(tan0,tan0)*dot(tan1,tan1))<sinEpsilon;if(!tangentsNearlyParallel"
"||dot(tan0,tan1)<0.){if(combinedEdgeID>=0.){strokeOutset=turn<0.?min(strokeOutset"
",0.):max(strokeOutset,0.);}}combinedEdgeID=max(combinedEdgeID,0.);}else{float"
" maxCombinedSegments=(maxEdges-numEdgesInJoin)-1.;numRadialSegments=max(ceil"
"(abs(rotation)*numRadialSegmentsPerRadian),1.);numRadialSegments=min(numRadialSegments"
",maxCombinedSegments);numParametricSegments=min(numParametricSegments,(maxCombinedSegments"
"-numRadialSegments)+1.);}float radsPerSegment=rotation/numRadialSegments;float"
" numCombinedSegments=(numParametricSegments+numRadialSegments)-1.;bool isFinalEdge"
"=combinedEdgeID>=numCombinedSegments;if(combinedEdgeID>numCombinedSegments)"
"{strokeOutset=0.;}if(abs(edgeID)==2.&&joinType>0.){strokeOutset*=$miter_extent"
"(cosTheta,joinType);}float2 tangent;float2 strokeCoord;if(combinedEdgeID!=0."
"&&!isFinalEdge){float2 A;float2 B;float2 C=p1-p0;float2 D=p3-p0;if(w>=0.){C"
"*=w;B=.5*D-C;A=(w-1.)*D;p1*=w;}else{float2 E=p2-p1;B=E-C;A=fma(float2(-3.),"
"E,D);}float2 B_=B*(numParametricSegments*2.);float2 C_=C*(numParametricSegments"
"*numParametricSegments);float lastParametricEdgeID=0.;float maxParametricEdgeID"
"=min(numParametricSegments-1.,combinedEdgeID);float negAbsRadsPerSegment=-abs"
"(radsPerSegment);float maxRotation0=(1.+combinedEdgeID)*abs(radsPerSegment)"
";for(int exp=4;exp>=0;--exp){float testParametricID=lastParametricEdgeID+exp2"
"(float(exp));if(testParametricID<=maxParametricEdgeID){float2 testTan=fma(float2"
"(testParametricID),A,B_);testTan=fma(float2(testParametricID),testTan,C_);float"
" cosRotation=dot(normalize(testTan),tan0);float maxRotation=fma(testParametricID"
",negAbsRadsPerSegment,maxRotation0);maxRotation=min(maxRotation,$PI);if(cosRotation"
">=cos(maxRotation)){lastParametricEdgeID=testParametricID;}}}float parametricT"
"=lastParametricEdgeID/numParametricSegments;float lastRadialEdgeID=combinedEdgeID"
"-lastParametricEdgeID;float angle0=acos(clamp(tan0.x,-1.,1.));angle0=tan0.y"
">=0.?angle0:-angle0;float radialAngle=fma(lastRadialEdgeID,radsPerSegment,angle0"
");tangent=float2(cos(radialAngle),sin(radialAngle));float2 norm=float2(-tangent"
".y,tangent.x);float a=dot(norm,A);float b_over_2=dot(norm,B);float c=dot(norm"
",C);float discr_over_4=max(b_over_2*b_over_2-a*c,0.);float q=sqrt(discr_over_4"
");if(b_over_2>0.){q=-q;}q-=b_over_2;float _5qa=(-.5*q)*a;float2 root=abs(fma"
"(q,q,_5qa))<abs(fma(a,c,_5qa))?float2(q,a):float2(c,q);float radialT=root.y"
"!=0.?root.x/root.y:0.;radialT=clamp(radialT,0.,1.);if(lastRadialEdgeID==0.)"
"{radialT=0.;}float T=max(parametricT,radialT);float2 ab=$unchecked_mix(p0,p1"
",T);float2 bc=$unchecked_mix(p1,p2,T);float2 cd=$unchecked_mix(p2,p3,T);float2"
" abc=$unchecked_mix(ab,bc,T);float2 bcd=$unchecked_mix(bc,cd,T);float2 abcd"
"=$unchecked_mix(abc,bcd,T);float u=$unchecked_mix(1.,w,T);float v=(w+1.)-u;"
"float uv=$unchecked_mix(u,v,T);if(T!=radialT){tangent=w>=0.?$robust_normalize_diff"
"(bc*u,ab*v):$robust_normalize_diff(bcd,abc);}strokeCoord=w>=0.?abc/uv:abcd;"
"}else{tangent=combinedEdgeID==0.?tan0:tan1;strokeCoord=combinedEdgeID==0.?p0"
":p3;}float2 ortho=float2(tangent.y,-tangent.x);strokeCoord+=ortho*(strokeRadius"
"*strokeOutset);if(isHairline){return float4(strokeCoord+translate,inverse(affineMatrix"
")*strokeCoord);}else{return float4(affineMatrix*strokeCoord+translate,strokeCoord"
");}}float2 ortho(float2 v){return float2(-v.y,v.x);}float3 calc_line_eq(float2"
" v,float2 p){float2 n=ortho(v);return float3(n,-dot(n,p));}";