| static constexpr char SKSL_MINIFIED_sksl_graphite_vert[] = |
| "const float $PI=3.14159274;const float $kCubicCurveType=0.;const float $kConicCurveType" |
| "=1.;const float $kTriangularConicCurveType=2.;$pure float curve_type_using_inf_support" |
| "(float4 p23){if(isinf(p23.z)){return $kTriangularConicCurveType;}if(isinf(p23" |
| ".w)){return $kConicCurveType;}return $kCubicCurveType;}$pure bool $is_conic_curve" |
| "(float curveType){return curveType!=$kCubicCurveType;}$pure bool $is_triangular_conic_curve" |
| "(float curveType){return curveType==$kTriangularConicCurveType;}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,float curveType){float2 localcoord;if($is_triangular_conic_curve" |
| "(curveType)){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($is_conic_curve(curveType)){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,float curveType){float2 p0=p01.xy;float2 p1=p01.zw;float2" |
| " p2=p23.xy;float2 p3=p23.zw;float w=-1.;if($is_conic_curve(curveType)){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" |
| ");}}float4 analytic_rrect_vertex_fn(float2 position,float2 normal,float normalScale" |
| ",float centerWeight,float4 xRadiiOrFlags,float4 radiiOrQuadXs,float4 ltrbOrQuadYs" |
| ",float4 center,float depth,float3x3 localToDevice,out float4 jacobian,out float4" |
| " edgeDistances,out float4 xRadii,out float4 yRadii,out float2 strokeParams," |
| "out float2 perPixelControl,out float2 stepLocalCoords){const int kCornerVertexCount" |
| "=9;const float kMiterScale=1.;const float kBevelScale=0.;const float kRoundScale" |
| "=.414213568;const float kEpsilon=.00024;float joinScale=kMiterScale;bool bidirectionalCoverage" |
| "=center.z<=0.;bool deviceSpaceDistances=false;float4 xs;float4 ys;float4 edgeAA" |
| "=float4(1.);bool strokedLine=false;if(xRadiiOrFlags.x<-1.){strokedLine=xRadiiOrFlags" |
| ".y>0.;xs=strokedLine?ltrbOrQuadYs.xxzz:ltrbOrQuadYs.xzzx;ys=ltrbOrQuadYs.yyww" |
| ";if(xRadiiOrFlags.y<0.){xRadii=-xRadiiOrFlags-2.;yRadii=radiiOrQuadXs;strokeParams" |
| "=float2(0.,1.);}else{xRadii=radiiOrQuadXs;yRadii=xRadii;strokeParams=xRadiiOrFlags" |
| ".zw;if(strokeParams.y<0.){joinScale=kRoundScale;}else if(strokeParams.y==0." |
| "){joinScale=kBevelScale;}}}else if(any(greaterThan(xRadiiOrFlags,float4(0.)" |
| "))){xs=ltrbOrQuadYs.xzzx;ys=ltrbOrQuadYs.yyww;xRadii=xRadiiOrFlags;yRadii=radiiOrQuadXs" |
| ";strokeParams=float2(0.,-1.);}else{xs=radiiOrQuadXs;ys=ltrbOrQuadYs;edgeAA=" |
| "-xRadiiOrFlags;xRadii=float4(0.);yRadii=float4(0.);strokeParams=float2(0.,1." |
| ");deviceSpaceDistances=true;}int cornerID=sk_VertexID/kCornerVertexCount;float2" |
| " cornerRadii=float2(xRadii[cornerID],yRadii[cornerID]);if(cornerID%2!=0){cornerRadii" |
| "=cornerRadii.yx;}float2 cornerAspectRatio=float2(1.);if(cornerRadii.x>0.&&cornerRadii" |
| ".y>0.){joinScale=kRoundScale;cornerAspectRatio=cornerRadii.yx;}float4 dx=xs" |
| "-xs.wxyz;float4 dy=ys-ys.wxyz;float4 edgeSquaredLen=dx*dx+dy*dy;float4 edgeMask" |
| "=sign(edgeSquaredLen);float4 edgeBias=float4(0.);float2 strokeRadius=float2" |
| "(strokeParams.x);if(any(equal(edgeMask,float4(0.)))){if(all(equal(edgeMask," |
| "float4(0.)))){dx=float4(0.,1.,0.,-1.);dy=float4(-1.,0.,1.,0.);edgeSquaredLen" |
| "=float4(1.);}else{bool triangle=((edgeMask.x+edgeMask.y)+edgeMask.z)+edgeMask" |
| ".w>2.5;float4 edgeX=triangle?dx.yzwx:dy.yzwx;float4 edgeY=triangle?dy.yzwx:" |
| "-dx.yzwx;dx=mix(edgeX,dx,edgeMask);dy=mix(edgeY,dy,edgeMask);edgeSquaredLen" |
| "=mix(edgeSquaredLen.yzwx,edgeSquaredLen,edgeMask);edgeAA=mix(edgeAA.yzwx,edgeAA" |
| ",edgeMask);if(!triangle&&joinScale==kBevelScale){strokeRadius*=float2(edgeMask" |
| "[cornerID],edgeMask.yzwx[cornerID]);edgeBias=(edgeMask-1.)*strokeParams.x;strokeParams" |
| ".y=1.;joinScale=kMiterScale;}}}float4 inverseEdgeLen=inversesqrt(edgeSquaredLen" |
| ");dx*=inverseEdgeLen;dy*=inverseEdgeLen;float2 xAxis=-float2(dx.yzwx[cornerID" |
| "],dy.yzwx[cornerID]);float2 yAxis=float2(dx[cornerID],dy[cornerID]);float2 localPos" |
| ";bool snapToCenter=false;if(normalScale<0.){if(center.w<0.||centerWeight*center" |
| ".z!=0.){snapToCenter=true;}else{float localAARadius=center.w;float2 insetRadii" |
| "=cornerRadii+(bidirectionalCoverage?-strokeRadius:strokeRadius);if((joinScale" |
| "==kMiterScale||insetRadii.x<=localAARadius)||insetRadii.y<=localAARadius){localPos" |
| "=insetRadii-localAARadius;}else{localPos=insetRadii*position-localAARadius*" |
| "normal;}}}else{localPos=(cornerRadii+strokeRadius)*(position+joinScale*position" |
| ".yx);}if(snapToCenter){localPos=center.xy;}else{localPos-=cornerRadii;localPos" |
| "=(float2(xs[cornerID],ys[cornerID])+xAxis*localPos.x)+yAxis*localPos.y;}edgeDistances" |
| "=(dy*(xs-localPos.x)-dx*(ys-localPos.y))+edgeBias;float3x3 deviceToLocal=inverse" |
| "(localToDevice);float3 devPos=localToDevice*float3(localPos,1.);jacobian=float4" |
| "(deviceToLocal[0].xy-deviceToLocal[0].z*localPos,deviceToLocal[1].xy-deviceToLocal" |
| "[1].z*localPos);if(deviceSpaceDistances){float4 gx=-dy*(deviceToLocal[0].x-" |
| "deviceToLocal[0].z*xs)+dx*(deviceToLocal[0].y-deviceToLocal[0].z*ys);float4" |
| " gy=-dy*(deviceToLocal[1].x-deviceToLocal[1].z*xs)+dx*(deviceToLocal[1].y-deviceToLocal" |
| "[1].z*ys);edgeDistances*=inversesqrt(gx*gx+gy*gy);edgeDistances+=(1.-edgeAA" |
| ")*abs(devPos.z);bool subpixelCoverage=edgeAA==float4(1.)&&dot(abs(dx*dx.yzwx" |
| "+dy*dy.yzwx),float4(1.))<kEpsilon;if(subpixelCoverage){float2 dim=edgeDistances" |
| ".xy+edgeDistances.zw;perPixelControl.y=1.+min(min(dim.x,dim.y),abs(devPos.z" |
| "));}else{perPixelControl.y=1.+abs(devPos.z);}}if(normalScale>0.&&devPos.z>0." |
| "){float2x2 J=float2x2(jacobian);float2 edgeAANormal=float2(edgeAA[cornerID]" |
| ",edgeAA.yzwx[cornerID])*normal;float2 nx=((cornerAspectRatio.x*edgeAANormal" |
| ".x)*perp(-yAxis))*J;float2 ny=((cornerAspectRatio.y*edgeAANormal.y)*perp(xAxis" |
| "))*J;bool isMidVertex=edgeAANormal.x!=0.&&edgeAANormal.y!=0.;if(joinScale==" |
| "kMiterScale&&isMidVertex){nx=normalize(nx);ny=normalize(ny);if(dot(nx,ny)<-" |
| ".8){float s=sign(cross_length_2d(nx,ny));nx=s*perp(nx);ny=-s*perp(ny);}}devPos" |
| ".xy+=devPos.z*normalize(nx+ny);if(deviceSpaceDistances){edgeDistances-=devPos" |
| ".z;}else{perPixelControl.y=-devPos.z;}}else if(!deviceSpaceDistances){perPixelControl" |
| ".y=0.;}if(centerWeight!=0.){perPixelControl.x=1.;}else{perPixelControl.x=float" |
| "(bidirectionalCoverage?-1.:0.);}if(strokedLine){jacobian=float4(float2x2(dy" |
| ".x,-dy.y,-dx.x,dx.y)*float2x2(jacobian));}stepLocalCoords=localPos;return float4" |
| "(devPos.xy,devPos.z*depth,devPos.z);}float4 per_edge_aa_quad_vertex_fn(float2" |
| " position,float2 normal,float normalScale,float centerWeight,float4 xRadiiOrFlags" |
| ",float4 radiiOrQuadXs,float4 ltrbOrQuadYs,float4 center,float depth,float3x3" |
| " localToDevice,out float4 jacobian,out float4 edgeDistances,out float4 xRadii" |
| ",out float4 yRadii,out float2 strokeParams,out float2 perPixelControl,out float2" |
| " stepLocalCoords){const int kCornerVertexCount=9;const float kMiterScale=1." |
| ";const float kBevelScale=0.;const float kRoundScale=.414213568;const float kEpsilon" |
| "=.00024;float joinScale=kMiterScale;bool bidirectionalCoverage=center.z<=0." |
| ";bool deviceSpaceDistances=false;float4 xs;float4 ys;float4 edgeAA=float4(1." |
| ");bool strokedLine=false;if(xRadiiOrFlags.x<-1.){strokedLine=xRadiiOrFlags." |
| "y>0.;xs=strokedLine?ltrbOrQuadYs.xxzz:ltrbOrQuadYs.xzzx;ys=ltrbOrQuadYs.yyww" |
| ";if(xRadiiOrFlags.y<0.){xRadii=-xRadiiOrFlags-2.;yRadii=radiiOrQuadXs;strokeParams" |
| "=float2(0.,1.);}else{xRadii=radiiOrQuadXs;yRadii=xRadii;strokeParams=xRadiiOrFlags" |
| ".zw;if(strokeParams.y<0.){joinScale=kRoundScale;}else if(strokeParams.y==0." |
| "){joinScale=kBevelScale;}}}else if(any(greaterThan(xRadiiOrFlags,float4(0.)" |
| "))){xs=ltrbOrQuadYs.xzzx;ys=ltrbOrQuadYs.yyww;xRadii=xRadiiOrFlags;yRadii=radiiOrQuadXs" |
| ";strokeParams=float2(0.,-1.);}else{xs=radiiOrQuadXs;ys=ltrbOrQuadYs;edgeAA=" |
| "-xRadiiOrFlags;xRadii=float4(0.);yRadii=float4(0.);strokeParams=float2(0.,1." |
| ");deviceSpaceDistances=true;}int cornerID=sk_VertexID/kCornerVertexCount;float2" |
| " cornerRadii=float2(xRadii[cornerID],yRadii[cornerID]);if(cornerID%2!=0){cornerRadii" |
| "=cornerRadii.yx;}float2 cornerAspectRatio=float2(1.);if(cornerRadii.x>0.&&cornerRadii" |
| ".y>0.){joinScale=kRoundScale;cornerAspectRatio=cornerRadii.yx;}float4 dx=xs" |
| "-xs.wxyz;float4 dy=ys-ys.wxyz;float4 edgeSquaredLen=dx*dx+dy*dy;float4 edgeMask" |
| "=sign(edgeSquaredLen);float4 edgeBias=float4(0.);float2 strokeRadius=float2" |
| "(strokeParams.x);if(any(equal(edgeMask,float4(0.)))){if(all(equal(edgeMask," |
| "float4(0.)))){dx=float4(0.,1.,0.,-1.);dy=float4(-1.,0.,1.,0.);edgeSquaredLen" |
| "=float4(1.);}else{bool triangle=((edgeMask.x+edgeMask.y)+edgeMask.z)+edgeMask" |
| ".w>2.5;float4 edgeX=triangle?dx.yzwx:dy.yzwx;float4 edgeY=triangle?dy.yzwx:" |
| "-dx.yzwx;dx=mix(edgeX,dx,edgeMask);dy=mix(edgeY,dy,edgeMask);edgeSquaredLen" |
| "=mix(edgeSquaredLen.yzwx,edgeSquaredLen,edgeMask);edgeAA=mix(edgeAA.yzwx,edgeAA" |
| ",edgeMask);if(!triangle&&joinScale==kBevelScale){strokeRadius*=float2(edgeMask" |
| "[cornerID],edgeMask.yzwx[cornerID]);edgeBias=(edgeMask-1.)*strokeParams.x;strokeParams" |
| ".y=1.;joinScale=kMiterScale;}}}float4 inverseEdgeLen=inversesqrt(edgeSquaredLen" |
| ");dx*=inverseEdgeLen;dy*=inverseEdgeLen;float2 xAxis=-float2(dx.yzwx[cornerID" |
| "],dy.yzwx[cornerID]);float2 yAxis=float2(dx[cornerID],dy[cornerID]);float2 localPos" |
| ";bool snapToCenter=false;if(normalScale<0.){if(center.w<0.||centerWeight*center" |
| ".z!=0.){snapToCenter=true;}else{float localAARadius=center.w;float2 insetRadii" |
| "=cornerRadii+(bidirectionalCoverage?-strokeRadius:strokeRadius);if((joinScale" |
| "==kMiterScale||insetRadii.x<=localAARadius)||insetRadii.y<=localAARadius){localPos" |
| "=insetRadii-localAARadius;}else{localPos=insetRadii*position-localAARadius*" |
| "normal;}}}else{localPos=(cornerRadii+strokeRadius)*(position+joinScale*position" |
| ".yx);}if(snapToCenter){localPos=center.xy;}else{localPos-=cornerRadii;localPos" |
| "=(float2(xs[cornerID],ys[cornerID])+xAxis*localPos.x)+yAxis*localPos.y;}edgeDistances" |
| "=(dy*(xs-localPos.x)-dx*(ys-localPos.y))+edgeBias;float3x3 deviceToLocal=inverse" |
| "(localToDevice);float3 devPos=localToDevice*float3(localPos,1.);jacobian=float4" |
| "(deviceToLocal[0].xy-deviceToLocal[0].z*localPos,deviceToLocal[1].xy-deviceToLocal" |
| "[1].z*localPos);if(deviceSpaceDistances){float4 gx=-dy*(deviceToLocal[0].x-" |
| "deviceToLocal[0].z*xs)+dx*(deviceToLocal[0].y-deviceToLocal[0].z*ys);float4" |
| " gy=-dy*(deviceToLocal[1].x-deviceToLocal[1].z*xs)+dx*(deviceToLocal[1].y-deviceToLocal" |
| "[1].z*ys);edgeDistances*=inversesqrt(gx*gx+gy*gy);edgeDistances+=(1.-edgeAA" |
| ")*abs(devPos.z);bool subpixelCoverage=edgeAA==float4(1.)&&dot(abs(dx*dx.yzwx" |
| "+dy*dy.yzwx),float4(1.))<kEpsilon;if(subpixelCoverage){float2 dim=edgeDistances" |
| ".xy+edgeDistances.zw;perPixelControl.y=1.+min(min(dim.x,dim.y),abs(devPos.z" |
| "));}else{perPixelControl.y=1.+abs(devPos.z);}}if(normalScale>0.&&devPos.z>0." |
| "){float2x2 J=float2x2(jacobian);float2 edgeAANormal=float2(edgeAA[cornerID]" |
| ",edgeAA.yzwx[cornerID])*normal;float2 nx=((cornerAspectRatio.x*edgeAANormal" |
| ".x)*perp(-yAxis))*J;float2 ny=((cornerAspectRatio.y*edgeAANormal.y)*perp(xAxis" |
| "))*J;bool isMidVertex=edgeAANormal.x!=0.&&edgeAANormal.y!=0.;if(joinScale==" |
| "kMiterScale&&isMidVertex){nx=normalize(nx);ny=normalize(ny);if(dot(nx,ny)<-" |
| ".8){float s=sign(cross_length_2d(nx,ny));nx=s*perp(nx);ny=-s*perp(ny);}}devPos" |
| ".xy+=devPos.z*normalize(nx+ny);if(deviceSpaceDistances){edgeDistances-=devPos" |
| ".z;}else{perPixelControl.y=-devPos.z;}}else if(!deviceSpaceDistances){perPixelControl" |
| ".y=0.;}if(centerWeight!=0.){perPixelControl.x=1.;}else{perPixelControl.x=float" |
| "(bidirectionalCoverage?-1.:0.);}if(strokedLine){jacobian=float4(float2x2(dy" |
| ".x,-dy.y,-dx.x,dx.y)*float2x2(jacobian));}stepLocalCoords=localPos;return float4" |
| "(devPos.xy,devPos.z*depth,devPos.z);}float4 text_vertex_fn(float2 baseCoords" |
| ",float4x4 subRunDeviceMatrix,float4x4 deviceToLocal,float2 atlasSizeInv,float2" |
| " size,float2 uvPos,float2 xyPos,float strikeToSourceScale,float depth,out float2" |
| " textureCoords,out float2 unormTexCoords,out float2 stepLocalCoords){baseCoords" |
| "*=size;float2 subRunCoords=strikeToSourceScale*baseCoords+xyPos;float4 position" |
| "=subRunDeviceMatrix*float4(subRunCoords,0.,1.);stepLocalCoords=(deviceToLocal" |
| "*position).xy;unormTexCoords=baseCoords+uvPos;textureCoords=unormTexCoords*" |
| "atlasSizeInv;return float4(position.xy,depth*position.w,position.w);}float4" |
| " coverage_mask_vertex_fn(float2 quadCoords,float3x3 maskToDeviceRemainder,float4" |
| " drawBounds,float4 maskBoundsIn,float2 deviceOrigin,float depth,float3x3 deviceToLocal" |
| ",out float4 maskBounds,out float2 textureCoords,out half invert,out float2 stepLocalCoords" |
| "){textureCoords=mix(drawBounds.xy,drawBounds.zw,quadCoords);float3 drawCoords" |
| "=maskToDeviceRemainder*float3(textureCoords+deviceOrigin,1.);float3 localCoords" |
| "=deviceToLocal*drawCoords;stepLocalCoords=localCoords.xy/localCoords.z;if(all" |
| "(lessThanEqual(maskBoundsIn.xy,maskBoundsIn.zw))){maskBounds=maskBoundsIn;invert" |
| "=0.;}else{maskBounds=maskBoundsIn.zwxy;invert=1.;}return float4(drawCoords." |
| "xy,depth*drawCoords.z,drawCoords.z);}float4 cover_bounds_vertex_fn(float2 corner" |
| ",float4 bounds,float depth,float3x3 matrix,out float2 stepLocalCoords){if(all" |
| "(lessThanEqual(bounds.xy,bounds.zw))){corner=mix(bounds.xy,bounds.zw,corner" |
| ");float3 devCorner=matrix*float3(corner,1.);stepLocalCoords=corner;return float4" |
| "(devCorner.xy,depth*devCorner.z,devCorner.z);}else{corner=mix(bounds.zw,bounds" |
| ".xy,corner);float3 localCoords=matrix*float3(corner,1.);stepLocalCoords=localCoords" |
| ".xy/localCoords.z;return float4(corner,depth,1.);}}"; |