92 #define BezierQuantum 200
247 if (clone_info == (
DrawInfo *) NULL)
252 if (clone_info->
primitive != (
char *) NULL)
254 if (draw_info->
geometry != (
char *) NULL)
282 if (draw_info->
text != (
char *) NULL)
284 if (draw_info->
font != (
char *) NULL)
286 if (draw_info->
metrics != (
char *) NULL)
288 if (draw_info->
family != (
char *) NULL)
293 if (draw_info->
encoding != (
char *) NULL)
300 if (draw_info->
density != (
char *) NULL)
317 "UnableToAllocateDashPattern");
332 "UnableToAllocateDashPattern");
337 if (draw_info->
clip_mask != (
char *) NULL)
379 #if defined(__cplusplus) || defined(c_plusplus)
408 #if defined(__cplusplus) || defined(c_plusplus)
422 p=polygon_info->
edges;
423 for (i=0; i < (ssize_t) polygon_info->
number_edges; i++)
450 for (i=0; i < (ssize_t) (number_points >> 1); i++)
453 points[i]=points[number_points-(i+1)];
454 points[number_points-(i+1)]=point;
495 sizeof(*polygon_info->
edges));
514 if ((points != (
PointInfo *) NULL) && (n >= 2))
516 if (edge == number_edges)
520 polygon_info->
edges,(
size_t) number_edges,
521 sizeof(*polygon_info->
edges));
549 point=path_info[i].
point;
560 next_direction=((path_info[i].
point.
y > point.
y) ||
561 ((path_info[i].point.
y == point.
y) &&
562 (path_info[i].
point.
x > point.
x))) ? 1 : -1;
563 if ((direction != 0) && (direction != next_direction))
569 if (edge == number_edges)
573 polygon_info->
edges,(
size_t) number_edges,
574 sizeof(*polygon_info->
edges));
601 direction=next_direction;
604 if (n == (ssize_t) number_points)
612 point=path_info[i].
point;
614 if (point.
x < bounds.
x1)
616 if (point.
x > bounds.
x2)
626 if (edge == number_edges)
630 polygon_info->
edges,(
size_t) number_edges,
631 sizeof(*polygon_info->
edges));
655 return(polygon_info);
698 "moveto ghostline" : p->
code ==
OpenCode ?
"moveto open" :
754 if (coordinates <= 0)
756 coordinates=(ssize_t) primitive_info[i].coordinates;
757 p=primitive_info[i].
point;
768 path_info[n].
code=code;
770 q=primitive_info[i].
point;
786 path_info[n].
point=p;
824 assert(draw_info != (
DrawInfo *) NULL);
826 if (draw_info->
primitive != (
char *) NULL)
828 if (draw_info->
text != (
char *) NULL)
830 if (draw_info->
geometry != (
char *) NULL)
838 if (draw_info->
font != (
char *) NULL)
840 if (draw_info->
metrics != (
char *) NULL)
842 if (draw_info->
family != (
char *) NULL)
844 if (draw_info->
encoding != (
char *) NULL)
846 if (draw_info->
density != (
char *) NULL)
857 if (draw_info->
clip_mask != (
char *) NULL)
891 assert(edge < polygon_info->number_edges);
895 if (edge < polygon_info->number_edges)
928 for (i=0; i < (ssize_t) polygon_info->
number_edges; i++)
980 inverse_edge.
x1=edge->
x1;
981 inverse_edge.
y1=edge->
y1;
982 inverse_edge.
x2=edge->
x2;
983 inverse_edge.
y2=edge->
y2;
984 z=affine->
ry*y+affine->
tx;
987 intercept=(-z/affine->
sx);
989 if (x > inverse_edge.
x1)
991 intercept=(-z+(double) image->
columns)/affine->
sx;
993 if (x < inverse_edge.
x2)
999 intercept=(-z+(double) image->
columns)/affine->
sx;
1001 if (x > inverse_edge.
x1)
1003 intercept=(-z/affine->
sx);
1005 if (x < inverse_edge.
x2)
1009 if ((z < 0.0) || ((size_t) floor(z+0.5) >= image->
columns))
1011 inverse_edge.
x2=edge->
x1;
1012 return(inverse_edge);
1017 z=affine->
sy*y+affine->
ty;
1020 intercept=(-z/affine->
rx);
1022 if (x > inverse_edge.
x1)
1024 intercept=(-z+(double) image->
rows)/affine->
rx;
1026 if (x < inverse_edge.
x2)
1032 intercept=(-z+(double) image->
rows)/affine->
rx;
1034 if (x > inverse_edge.
x1)
1036 intercept=(-z/affine->
rx);
1038 if (x < inverse_edge.
x2)
1042 if ((z < 0.0) || ((size_t) floor(z+0.5) >= image->
rows))
1044 inverse_edge.
x2=edge->
x2;
1045 return(inverse_edge);
1047 return(inverse_edge);
1060 inverse_affine.
sx=determinant*affine->
sy;
1061 inverse_affine.
rx=determinant*(-affine->
rx);
1062 inverse_affine.
ry=determinant*(-affine->
ry);
1063 inverse_affine.
sy=determinant*affine->
sx;
1064 inverse_affine.
tx=(-affine->
tx)*inverse_affine.
sx-affine->
ty*
1066 inverse_affine.
ty=(-affine->
tx)*inverse_affine.
rx-affine->
ty*
1068 return(inverse_affine);
1078 static inline double MagickMax(
const double x,
const double y)
1085 static inline double MagickMin(
const double x,
const double y)
1131 assert(image != (
Image *) NULL);
1135 assert(source != (
const Image *) NULL);
1140 extent[1].
x=(double) source->
columns-1.0;
1142 extent[2].
x=(
double) source->
columns-1.0;
1143 extent[2].
y=(double) source->
rows-1.0;
1145 extent[3].
y=(
double) source->
rows-1.0;
1146 for (i=0; i < 4; i++)
1149 extent[i].
x=point.
x*affine->
sx+point.
y*affine->
ry+affine->
tx;
1150 extent[i].
y=point.
x*affine->
rx+point.
y*affine->
sy+affine->
ty;
1154 for (i=1; i < 4; i++)
1156 if (min.
x > extent[i].
x)
1158 if (min.
y > extent[i].
y)
1160 if (max.
x < extent[i].
x)
1162 if (max.
y < extent[i].
y)
1178 start=(ssize_t) ceil(edge.
y1-0.5);
1179 stop=(ssize_t) floor(edge.
y2+0.5);
1182 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1183 #pragma omp parallel for schedule(static,4) shared(status) \
1184 magick_threads(source,image,1,1)
1186 for (y=start; y <= stop; y++)
1210 inverse_edge=
AffineEdge(source,&inverse_affine,(
double) y,&edge);
1211 if (inverse_edge.
x2 < inverse_edge.
x1)
1214 0.5),y,(
size_t) (floor(inverse_edge.
x2+0.5)-ceil(inverse_edge.
x1-0.5)+1),
1222 for (x=(ssize_t) ceil(inverse_edge.
x1-0.5); x <= (ssize_t) floor(inverse_edge.
x2+0.5); x++)
1224 point.
x=(double) x*inverse_affine.
sx+y*inverse_affine.
ry+
1226 point.
y=(
double) x*inverse_affine.
rx+y*inverse_affine.
sy+
1232 composite.
opacity,&composite);
1303 if (clone_info->
density != (
char *) NULL)
1312 resolution.
x=geometry_info.
rho;
1313 resolution.
y=geometry_info.
sigma;
1315 resolution.
y=resolution.
x;
1326 for (i=1; i < (ssize_t) polygon_info->
number_edges; i++)
1338 bounds.
x1=bounds.
x1 < 0.0 ? 0.0 : bounds.
x1 >= (double)
1341 bounds.
y1=bounds.
y1 < 0.0 ? 0.0 : bounds.
y1 >= (double)
1342 image->
rows ? (
double) image->
rows-1 : bounds.
y1;
1344 bounds.
x2=bounds.
x2 < 0.0 ? 0.0 : bounds.
x2 >= (double)
1347 bounds.
y2=bounds.
y2 < 0.0 ? 0.0 : bounds.
y2 >= (double)
1348 image->
rows ? (
double) image->
rows-1 : bounds.
y2;
1349 for (i=0; i < (ssize_t) polygon_info->
number_edges; i++)
1364 coordinates=(ssize_t) primitive_info[0].coordinates;
1370 start.
x=(double) (bounds.
x1-mid);
1371 start.
y=(double) (bounds.
y1-mid);
1372 end.
x=(double) (bounds.
x2+mid);
1373 end.
y=(double) (bounds.
y2+mid);
1377 coordinates=(ssize_t) primitive_info[0].coordinates;
1411 const DrawInfo *draw_info,
const char *name)
1425 assert(image != (
Image *) NULL);
1429 assert(draw_info != (
const DrawInfo *) NULL);
1432 if (value == (
const char *) NULL)
1441 if (clip_mask == (
Image *) NULL)
1527 assert(draw_info != (
const DrawInfo *) NULL);
1533 number_vertices=(size_t) i;
1535 (2UL*number_vertices+1UL),
sizeof(*dash_polygon));
1538 dash_polygon[0]=primitive_info[0];
1543 for (n=0; offset > 0.0; j=0)
1547 length=scale*(draw_info->
dash_pattern[n]+(n == 0 ? -0.5 : 0.5));
1548 if (offset > length)
1552 length=scale*(draw_info->
dash_pattern[n]+(n == 0 ? -0.5 : 0.5));
1555 if (offset < length)
1567 for (i=1; i < (ssize_t) number_vertices; i++)
1569 dx=primitive_info[i].
point.
x-primitive_info[i-1].
point.
x;
1570 dy=primitive_info[i].
point.
y-primitive_info[i-1].
point.
y;
1571 maximum_length=hypot((
double) dx,dy);
1577 length=scale*(draw_info->
dash_pattern[n]+(n == 0 ? -0.5 : 0.5));
1579 for (total_length=0.0; (total_length+length) <= maximum_length; )
1581 total_length+=length;
1582 if ((n & 0x01) != 0)
1584 dash_polygon[0]=primitive_info[0];
1585 dash_polygon[0].
point.
x=(double) (primitive_info[i-1].point.x+dx*
1586 total_length/maximum_length);
1587 dash_polygon[0].
point.
y=(double) (primitive_info[i-1].point.y+dy*
1588 total_length/maximum_length);
1593 if ((j+1) > (ssize_t) (2*number_vertices))
1595 dash_polygon[j]=primitive_info[i-1];
1596 dash_polygon[j].
point.
x=(double) (primitive_info[i-1].point.x+dx*
1597 total_length/maximum_length);
1598 dash_polygon[j].
point.
y=(double) (primitive_info[i-1].point.y+dy*
1599 total_length/maximum_length);
1609 length=scale*(draw_info->
dash_pattern[n]+(n == 0 ? -0.5 : 0.5));
1611 length-=(maximum_length-total_length);
1612 if ((n & 0x01) != 0)
1614 dash_polygon[j]=primitive_info[i];
1618 if ((total_length <= maximum_length) && ((n & 0x01) == 0) && (j > 1))
1620 dash_polygon[j]=primitive_info[i-1];
1681 primitive_info->
point=point;
1686 #define RenderImageTag "Render/Image"
1750 assert(image != (
Image *) NULL);
1754 assert(draw_info != (
DrawInfo *) NULL);
1758 if ((draw_info->
primitive == (
char *) NULL) ||
1767 if (primitive == (
char *) NULL)
1769 primitive_extent=(double) strlen(primitive);
1776 sizeof(*graphic_context));
1777 if (graphic_context == (
DrawInfo **) NULL)
1785 sizeof(*primitive_info));
1789 for ( ; n >= 0; n--)
1807 for (q=primitive; *q !=
'\0'; )
1813 if (*keyword ==
'\0')
1815 if (*keyword ==
'#')
1820 while ((*q !=
'\n') && (*q !=
'\0'))
1824 p=q-strlen(keyword)-1;
1826 current=graphic_context[n]->
affine;
1896 (void)
CloneString(&graphic_context[n]->clip_mask,token);
1898 graphic_context[n]->clip_mask);
1909 if (fill_rule == -1)
1925 if (clip_units == -1)
1988 (void)
CloneString(&graphic_context[n]->encoding,token);
2003 &graphic_context[n]->fill_pattern);
2027 factor=strchr(token,
'%') != (
char *) NULL ? 0.01 : 1.0;
2040 if (fill_rule == -1)
2051 (void)
CloneString(&graphic_context[n]->font,token);
2053 graphic_context[n]->font=(
char *)
2060 (void)
CloneString(&graphic_context[n]->family,token);
2104 graphic_context[n]->
weight=0;
2106 graphic_context[n]->
weight=700;
2108 if (graphic_context[n]->weight <= 800)
2109 graphic_context[n]->
weight+=100;
2111 if (graphic_context[n]->weight >= 100)
2112 graphic_context[n]->
weight-=100;
2114 graphic_context[n]->
weight=400;
2227 factor=strchr(token,
'%') != (
char *) NULL ? 0.01 : 1.0;
2276 "UnbalancedGraphicContextPushPop",
"`%s'",token);
2280 if (graphic_context[n]->clip_mask != (
char *) NULL)
2282 graphic_context[n-1]->clip_mask) != 0)
2303 for (p=q; *q !=
'\0'; )
2352 for (p=q; *q !=
'\0'; )
2379 "%gx%g%+.15g%+.15g",
2382 bounds.
x1,bounds.
y1);
2406 (
char **) NULL)+0.5);
2411 (
char **) NULL)+0.5);
2412 for (p=q; *q !=
'\0'; )
2427 "%.20gx%.20g%+.20g%+.20g",(
double) bounds.
width,(double)
2428 bounds.
height,(
double) bounds.
x,(double) bounds.
y);
2437 graphic_context,(
size_t) (n+1),
sizeof(*graphic_context));
2438 if (graphic_context == (
DrawInfo **) NULL)
2442 "MemoryAllocationFailed",
"`%s'",image->
filename);
2446 graphic_context[n-1]);
2518 &start_color,&stop_color);
2519 start_color=stop_color;
2529 &graphic_context[n]->stroke_pattern);
2559 if (graphic_context[n]->dash_pattern != (
double *) NULL)
2579 sizeof(*graphic_context[n]->dash_pattern));
2580 if (graphic_context[n]->dash_pattern == (
double *) NULL)
2584 "MemoryAllocationFailed",
"`%s'",image->
filename);
2587 for (j=0; j < x; j++)
2595 if ((x & 0x01) != 0)
2596 for ( ; j < (2*x); j++)
2597 graphic_context[n]->dash_pattern[j]=
2598 graphic_context[n]->dash_pattern[j-x];
2651 factor=strchr(token,
'%') != (
char *) NULL ? 0.01 : 1.0;
2738 (
char **) NULL)-0.5);
2743 (
char **) NULL)-0.5);
2748 token,(
char **) NULL)+0.5);
2753 token,(
char **) NULL)+0.5);
2767 if ((affine.
sx != 1.0) || (affine.
rx != 0.0) || (affine.
ry != 0.0) ||
2768 (affine.
sy != 1.0) || (affine.
tx != 0.0) || (affine.
ty != 0.0))
2791 primitive_info[0].
point.
x=0.0;
2792 primitive_info[0].
point.
y=0.0;
2793 for (x=0; *q !=
'\0'; x++)
2809 primitive_info[i].
primitive=primitive_type;
2810 primitive_info[i].
point=point;
2814 if (i < (ssize_t) number_points)
2818 (
size_t) number_points,
sizeof(*primitive_info));
2826 primitive_info[j].
primitive=primitive_type;
2829 primitive_info[j].
text=(
char *) NULL;
2833 bounds.
x1=primitive_info[j].
point.
x;
2834 bounds.
y1=primitive_info[j].
point.
y;
2835 bounds.
x2=primitive_info[j].
point.
x;
2836 bounds.
y2=primitive_info[j].
point.
y;
2837 for (k=1; k < (ssize_t) primitive_info[j].coordinates; k++)
2839 point=primitive_info[j+k].
point;
2840 if (point.
x < bounds.
x1)
2842 if (point.
y < bounds.
y1)
2844 if (point.
x > bounds.
x2)
2846 if (point.
y > bounds.
y2)
2853 switch (primitive_type)
2867 if (primitive_info[j].coordinates > 107)
2869 DrawError,
"TooManyBezierCoordinates",
"`%s'",token);
2882 for (s=token; *s !=
'\0'; s=t)
2908 alpha=bounds.
x2-bounds.
x1;
2909 beta=bounds.
y2-bounds.
y1;
2910 radius=hypot((
double) alpha,(
double) beta);
2917 if ((
size_t) (i+length) >= number_points)
2922 number_points+=length+1;
2924 (
size_t) number_points,
sizeof(*primitive_info));
2933 switch (primitive_type)
2938 if (primitive_info[j].coordinates != 1)
2943 TracePoint(primitive_info+j,primitive_info[j].point);
2944 i=(ssize_t) (j+primitive_info[j].coordinates);
2949 if (primitive_info[j].coordinates != 2)
2954 TraceLine(primitive_info+j,primitive_info[j].point,
2955 primitive_info[j+1].point);
2956 i=(ssize_t) (j+primitive_info[j].coordinates);
2961 if (primitive_info[j].coordinates != 2)
2967 primitive_info[j+1].point);
2968 i=(ssize_t) (j+primitive_info[j].coordinates);
2973 if (primitive_info[j].coordinates != 3)
2979 primitive_info[j+1].point,primitive_info[j+2].point);
2980 i=(ssize_t) (j+primitive_info[j].coordinates);
2985 if (primitive_info[j].coordinates != 3)
2990 TraceArc(primitive_info+j,primitive_info[j].point,
2991 primitive_info[j+1].point,primitive_info[j+2].point);
2992 i=(ssize_t) (j+primitive_info[j].coordinates);
2997 if (primitive_info[j].coordinates != 3)
3003 primitive_info[j+1].point,primitive_info[j+2].point);
3004 i=(ssize_t) (j+primitive_info[j].coordinates);
3009 if (primitive_info[j].coordinates != 2)
3014 TraceCircle(primitive_info+j,primitive_info[j].point,
3015 primitive_info[j+1].point);
3016 i=(ssize_t) (j+primitive_info[j].coordinates);
3023 primitive_info[i]=primitive_info[j];
3031 if (primitive_info[j].coordinates < 3)
3036 TraceBezier(primitive_info+j,primitive_info[j].coordinates);
3037 i=(ssize_t) (j+primitive_info[j].coordinates);
3042 i=(ssize_t) (j+
TracePath(primitive_info+j,token));
3051 if (primitive_info[j].coordinates != 1)
3068 if (primitive_info[j].coordinates != 1)
3080 if (primitive_info[j].coordinates != 2)
3104 point=primitive_info[i].
point;
3109 point=primitive_info[i].
point;
3110 if (point.
x < graphic_context[n]->
bounds.
x1)
3112 if (point.
y < graphic_context[n]->
bounds.
y1)
3114 if (point.
x > graphic_context[n]->
bounds.
x2)
3116 if (point.
y > graphic_context[n]->
bounds.
y2)
3120 if (i >= (ssize_t) number_points)
3125 if ((n != 0) && (graphic_context[n]->
clip_mask != (
char *) NULL) &&
3127 graphic_context[n-1]->clip_mask) != 0))
3129 graphic_context[n]->clip_mask);
3130 (void)
DrawPrimitive(image,graphic_context[n],primitive_info);
3132 if (primitive_info->
text != (
char *) NULL)
3134 primitive_info->
text);
3149 for ( ; n >= 0; n--)
3185 const ssize_t x,
const ssize_t y)
3187 switch (gradient->
type)
3206 p.
x=gradient_vector->
x2-gradient_vector->
x1;
3207 p.
y=gradient_vector->
y2-gradient_vector->
y1;
3208 q.
x=(double) x-gradient_vector->
x1;
3209 q.
y=(
double) y-gradient_vector->
y1;
3210 length=sqrt(q.
x*q.
x+q.
y*q.
y);
3211 gamma=sqrt(p.
x*p.
x+p.
y*p.
y)*length;
3213 scale=p.
x*q.
x+p.
y*q.
y;
3214 offset=gamma*scale*length;
3228 length=sqrt(v.
x*v.
x+v.
y*v.
y);
3231 offset=length/gradient->
radius;
3274 assert(image != (
Image *) NULL);
3278 assert(draw_info != (
const DrawInfo *) NULL);
3281 point.
x=gradient_vector->
x2-gradient_vector->
x1;
3282 point.
y=gradient_vector->
y2-gradient_vector->
y1;
3283 length=sqrt(point.
x*point.
x+point.
y*point.
y);
3289 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3290 #pragma omp parallel for schedule(static,4) shared(status) \
3291 magick_threads(image,image,1,1)
3293 for (y=bounding_box.
y; y < (ssize_t) bounding_box.
height; y++)
3330 for (x=bounding_box.
x; x < (ssize_t) bounding_box.
width; x++)
3333 switch (gradient->
spread)
3338 if ((x != (ssize_t) ceil(gradient_vector->
x1-0.5)) ||
3339 (y != (ssize_t) ceil(gradient_vector->
y1-0.5)))
3346 if (offset < gradient->stops[i].offset)
3348 if ((offset < 0.0) || (i == 0))
3351 if ((offset > 1.0) || (i == (ssize_t) gradient->
number_stops))
3366 if ((x != (ssize_t) ceil(gradient_vector->
x1-0.5)) ||
3367 (y != (ssize_t) ceil(gradient_vector->
y1-0.5)))
3375 if ((ssize_t) fmod(offset,2.0) == 0)
3376 offset=fmod(offset,1.0);
3378 offset=1.0-fmod(offset,1.0);
3380 if (offset < gradient->stops[i].offset)
3408 if ((x != (ssize_t) ceil(gradient_vector->
x1-0.5)) ||
3409 (y != (ssize_t) ceil(gradient_vector->
y1-0.5)))
3414 repeat=fmod(offset,length);
3416 repeat=length-fmod(-repeat,length);
3418 repeat=fmod(offset,length);
3419 antialias=(repeat < length) && ((repeat+1.0) > length) ?
3421 offset=repeat/length;
3425 repeat=fmod(offset,gradient->
radius);
3427 repeat=gradient->
radius-fmod(-repeat,gradient->
radius);
3429 repeat=fmod(offset,gradient->
radius);
3430 antialias=repeat+1.0 > gradient->
radius ?
3432 offset=repeat/gradient->
radius;
3436 if (offset < gradient->stops[i].offset)
3452 alpha=length-repeat;
3454 alpha=gradient->
radius-repeat;
3465 pixel.opacity,&pixel);
3524 assert(image != (
Image *) NULL);
3528 assert(draw_info != (
const DrawInfo *) NULL);
3529 assert(name != (
const char *) NULL);
3532 if (path == (
const char *) NULL)
3536 if (geometry == (
const char *) NULL)
3538 if ((*pattern) != (
Image *) NULL)
3549 "begin pattern-path %s %s",name,geometry);
3599 return(polygon_info);
3606 *restrict path_info;
3619 sizeof(*polygon_info));
3625 if (path_info == (
PathInfo *) NULL)
3627 for (i=0; i < (ssize_t) number_threads; i++)
3634 return(polygon_info);
3639 const ssize_t y,
double *stroke_opacity)
3666 *stroke_opacity=0.0;
3667 subpath_opacity=0.0;
3668 p=polygon_info->
edges;
3669 for (j=0; j < (ssize_t) polygon_info->
number_edges; j++, p++)
3671 if ((
double) y <= (p->
bounds.
y1-mid-0.5))
3673 if ((
double) y > (p->
bounds.
y2+mid+0.5))
3678 if (((
double) x <= (p->
bounds.
x1-mid-0.5)) ||
3679 ((
double) x > (p->
bounds.
x2+mid+0.5)))
3684 if ((
double) y <= (p->
points[i-1].
y-mid-0.5))
3686 if ((
double) y > (p->
points[i].
y+mid+0.5))
3697 delta.
x=(q+1)->x-q->
x;
3698 delta.
y=(q+1)->y-q->
y;
3699 beta=delta.
x*(x-q->
x)+delta.
y*(y-q->
y);
3702 delta.
x=(double) x-q->
x;
3703 delta.
y=(
double) y-q->
y;
3704 distance=delta.
x*delta.
x+delta.
y*delta.
y;
3708 alpha=delta.
x*delta.
x+delta.
y*delta.
y;
3711 delta.
x=(double) x-(q+1)->x;
3712 delta.
y=(double) y-(q+1)->y;
3713 distance=delta.
x*delta.
x+delta.
y*delta.
y;
3718 beta=delta.
x*(y-q->
y)-delta.
y*(x-q->
x);
3719 distance=alpha*beta*beta;
3729 if ((*stroke_opacity < 1.0) &&
3730 (distance <= ((alpha+0.25)*(alpha+0.25))))
3733 if (distance <= ((alpha+0.25)*(alpha+0.25)))
3734 *stroke_opacity=1.0;
3738 if (distance != 1.0)
3739 beta=sqrt((
double) distance);
3741 if (*stroke_opacity < ((alpha-0.25)*(alpha-0.25)))
3742 *stroke_opacity=(alpha-0.25)*(alpha-0.25);
3746 if ((fill ==
MagickFalse) || (distance > 1.0) || (subpath_opacity >= 1.0))
3748 if (distance <= 0.0)
3750 subpath_opacity=1.0;
3758 if (distance != 1.0)
3759 beta=sqrt(distance);
3762 if (subpath_opacity < (alpha*alpha))
3763 subpath_opacity=alpha*alpha;
3771 if (subpath_opacity >= 1.0)
3777 p=polygon_info->
edges;
3778 for (j=0; j < (ssize_t) polygon_info->
number_edges; j++, p++)
3782 if (((
double) y > p->
bounds.
y2) || ((double) x <= p->bounds.x1))
3791 if ((
double) y <= p->
points[i].
y)
3794 if ((((q+1)->x-q->
x)*(y-q->
y)) <= (((q+1)->y-q->
y)*(x-q->
x)))
3805 return(subpath_opacity);
3825 **restrict polygon_info;
3844 assert(image != (
Image *) NULL);
3848 assert(draw_info != (
DrawInfo *) NULL);
3863 bounds=polygon_info[0]->edges[0].bounds;
3864 for (i=1; i < (ssize_t) polygon_info[0]->number_edges; i++)
3866 p=polygon_info[0]->edges+i;
3876 bounds.
x1-=(mid+1.0);
3877 bounds.
x1=bounds.
x1 < 0.0 ? 0.0 : (size_t) ceil(bounds.
x1-0.5) >=
3879 bounds.
y1-=(mid+1.0);
3880 bounds.
y1=bounds.
y1 < 0.0 ? 0.0 : (size_t) ceil(bounds.
y1-0.5) >=
3881 image->
rows ? (double) image->
rows-1 : bounds.
y1;
3882 bounds.
x2+=(mid+1.0);
3883 bounds.
x2=bounds.
x2 < 0.0 ? 0.0 : (size_t) floor(bounds.
x2+0.5) >=
3885 bounds.
y2+=(mid+1.0);
3886 bounds.
y2=bounds.
y2 < 0.0 ? 0.0 : (size_t) floor(bounds.
y2+0.5) >=
3887 image->
rows ? (double) image->
rows-1 : bounds.
y2;
3896 start=(ssize_t) ceil(bounds.
y1-0.5);
3897 stop=(ssize_t) floor(bounds.
y2+0.5);
3898 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3899 #pragma omp parallel for schedule(static,4) shared(status) \
3900 magick_threads(image,image,1,1)
3902 for (y=start; y <= stop; y++)
3919 start=(ssize_t) ceil(bounds.
x1-0.5);
3920 stop=(ssize_t) floor(bounds.
x2+0.5);
3929 for ( ; x <= stop; x++)
3931 if ((x == (ssize_t) ceil(primitive_info->
point.
x-0.5)) &&
3932 (y == (ssize_t) ceil(primitive_info->
point.
y-0.5)))
3944 " end draw-polygon");
3952 start=(ssize_t) ceil(bounds.
y1-0.5);
3953 stop=(ssize_t) floor(bounds.
y2+0.5);
3954 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3955 #pragma omp parallel for schedule(static,4) shared(status) \
3956 magick_threads(image,image,1,1)
3958 for (y=start; y <= stop; y++)
3983 start=(ssize_t) ceil(bounds.
x1-0.5);
3984 stop=(ssize_t) floor(bounds.
x2+0.5);
3992 for (x=start; x <= stop; x++)
3998 draw_info->
fill_rule,x,y,&stroke_opacity);
4001 fill_opacity=fill_opacity > 0.25 ? 1.0 : 0.0;
4002 stroke_opacity=stroke_opacity > 0.25 ? 1.0 : 0.0;
4080 x=(ssize_t) ceil(primitive_info->
point.
x-0.5);
4081 y=(ssize_t) ceil(primitive_info->
point.
y-0.5);
4087 "PointPrimitive %.20g,%.20g %s",(double) x,(
double) y,
4088 methods[primitive_info->
method]);
4094 "ColorPrimitive %.20g,%.20g %s",(double) x,(
double) y,
4095 methods[primitive_info->
method]);
4101 "MattePrimitive %.20g,%.20g %s",(double) x,(
double) y,
4102 methods[primitive_info->
method]);
4108 "TextPrimitive %.20g,%.20g",(double) x,(
double) y);
4114 "ImagePrimitive %.20g,%.20g",(double) x,(
double) y);
4121 p=primitive_info[0].
point;
4126 point=primitive_info[i].
point;
4127 if (coordinates <= 0)
4129 coordinates=(ssize_t) primitive_info[i].coordinates;
4131 " begin open (%.20g)",(double) coordinates);
4134 point=primitive_info[i].
point;
4138 " %.20g: %.18g,%.18g",(double) coordinates,point.
x,point.
y);
4141 " %.20g: %g %g (duplicate)",(
double) coordinates,point.
x,point.
y);
4144 if (coordinates > 0)
4149 (double) coordinates);
4152 (
double) coordinates);
4178 " begin draw-primitive");
4180 " affine: %g %g %g %g %g %g",draw_info->
affine.
sx,
4190 x=(ssize_t) ceil(primitive_info->
point.
x-0.5);
4191 y=(ssize_t) ceil(primitive_info->
point.
y-0.5);
4203 if ((y < 0) || (y >= (ssize_t) image->
rows))
4205 if ((x < 0) || (x >= (ssize_t) image->
columns))
4218 switch (primitive_info->
method)
4242 for (y=0; y < (ssize_t) image->
rows; y++)
4251 for (x=0; x < (ssize_t) image->
columns; x++)
4290 for (y=0; y < (ssize_t) image->
rows; y++)
4302 for (x=0; x < (ssize_t) image->
columns; x++)
4320 switch (primitive_info->
method)
4349 for (y=0; y < (ssize_t) image->
rows; y++)
4361 for (x=0; x < (ssize_t) image->
columns; x++)
4404 for (y=0; y < (ssize_t) image->
rows; y++)
4416 for (x=0; x < (ssize_t) image->
columns; x++)
4439 if (primitive_info->
text == (
char *) NULL)
4471 if (primitive_info->
text == (
char *) NULL)
4484 if (composite_image == (
Image *) NULL)
4487 NULL,(
void *) NULL);
4488 x1=(ssize_t) ceil(primitive_info[1].point.x-0.5);
4489 y1=(ssize_t) ceil(primitive_info[1].point.y-0.5);
4490 if (((x1 != 0L) && (x1 != (ssize_t) composite_image->
columns)) ||
4491 ((y1 != 0L) && (y1 != (ssize_t) composite_image->
rows)))
4500 primitive_info[1].point.x,primitive_info[1].
point.
y);
4513 "%.20gx%.20g%+.20g%+.20g",(
double) composite_image->
columns,(double)
4514 composite_image->
rows,(
double) geometry.
x,(double) geometry.
y);
4517 affine=draw_info->
affine;
4518 affine.
tx=(double) geometry.
x;
4519 affine.
ty=(
double) geometry.
y;
4525 geometry.
x,geometry.
y);
4569 (primitive_info[i-1].
point.
x == primitive_info[0].
point.
x) &&
4570 (primitive_info[i-1].point.y == primitive_info[0].
point.
y) ?
4572 i=(ssize_t) primitive_info[0].coordinates;
4638 for (i=0; i < 4; i++)
4639 linecap[i]=(*primitive_info);
4671 " begin draw-stroke-polygon");
4700 " end draw-stroke-polygon");
4732 affine_matrix->
sx=1.0;
4733 affine_matrix->
sy=1.0;
4775 assert(draw_info != (
DrawInfo *) NULL);
4790 if (clone_info->
font != (
char *) NULL)
4792 if (clone_info->
density != (
char *) NULL)
4806 if (option != (
const char *) NULL)
4809 if (option != (
const char *) NULL)
4812 if (option != (
const char *) NULL)
4816 if (option != (
const char *) NULL)
4819 if (option != (
const char *) NULL)
4823 if (option != (
const char *) NULL)
4826 if (option != (
const char *) NULL)
4829 if (option != (
const char *) NULL)
4832 if (option != (
const char *) NULL)
4835 if (option != (
const char *) NULL)
4868 static inline double Permutate(
const ssize_t n,
const ssize_t k)
4877 for (i=k+1; i <= n; i++)
4879 for (i=1; i <= (n-k); i++)
4907 center.
x=0.5*(end.
x+start.
x);
4908 center.
y=0.5*(end.
y+start.
y);
4909 radii.
x=fabs(center.
x-start.
x);
4910 radii.
y=fabs(center.
y-start.
y);
4944 if ((start.
x == end.
x) && (start.
y == end.
y))
4949 radii.
x=fabs(arc.
x);
4950 radii.
y=fabs(arc.
y);
4951 if ((radii.
x == 0.0) || (radii.
y == 0.0))
4958 center.
x=(double) (cosine*(end.
x-start.
x)/2+sine*(end.
y-start.
y)/2);
4959 center.
y=(double) (cosine*(end.
y-start.
y)/2-sine*(end.
x-start.
x)/2);
4960 delta=(center.
x*center.
x)/(radii.
x*radii.
x)+(center.
y*center.
y)/
4969 radii.
x*=sqrt((
double) delta);
4970 radii.
y*=sqrt((
double) delta);
4972 points[0].
x=(double) (cosine*start.
x/radii.
x+sine*start.
y/radii.
x);
4973 points[0].
y=(double) (cosine*start.
y/radii.
y-sine*start.
x/radii.
y);
4974 points[1].
x=(double) (cosine*end.
x/radii.
x+sine*end.
y/radii.
x);
4975 points[1].
y=(double) (cosine*end.
y/radii.
y-sine*end.
x/radii.
y);
4976 alpha=points[1].
x-points[0].
x;
4977 beta=points[1].
y-points[0].
y;
4983 factor=sqrt((
double) factor);
4984 if (sweep == large_arc)
4987 center.
x=(double) ((points[0].x+points[1].x)/2-factor*beta);
4988 center.
y=(double) ((points[0].y+points[1].y)/2+factor*alpha);
4989 alpha=atan2(points[0].y-center.
y,points[0].
x-center.
x);
4990 theta=atan2(points[1].y-center.
y,points[1].
x-center.
x)-alpha;
4996 arc_segments=(size_t) ceil(fabs((
double) (theta/(0.5*
MagickPI+
4999 for (i=0; i < (ssize_t) arc_segments; i++)
5001 beta=0.5*((alpha+(i+1)*theta/arc_segments)-(alpha+i*theta/arc_segments));
5005 points[0].
x=(double) (center.
x+cos(fmod((
double) (alpha+(
double) i*theta/
5008 points[0].
y=(double) (center.
y+sin(fmod((
double) (alpha+(
double) i*theta/
5011 points[2].
x=(double) (center.
x+cos(fmod((
double) (alpha+(double) (i+1)*
5013 points[2].
y=(double) (center.
y+sin(fmod((
double) (alpha+(double) (i+1)*
5015 points[1].
x=(double) (points[2].x+gamma*sin(fmod((
double) (alpha+(double)
5017 points[1].
y=(double) (points[2].y-gamma*cos(fmod((
double) (alpha+(double)
5019 p->
point.
x=(p == primitive_info) ? start.
x : (p-1)->point.x;
5020 p->
point.
y=(p == primitive_info) ? start.
y : (p-1)->point.y;
5021 (p+1)->point.x=(
double) (cosine*radii.
x*points[0].
x-sine*radii.
y*
5023 (p+1)->point.y=(
double) (sine*radii.
x*points[0].
x+cosine*radii.
y*
5025 (p+2)->point.x=(
double) (cosine*radii.
x*points[1].
x-sine*radii.
y*
5027 (p+2)->point.y=(
double) (sine*radii.
x*points[1].
x+cosine*radii.
y*
5029 (p+3)->point.x=(
double) (cosine*radii.
x*points[2].
x-sine*radii.
y*
5031 (p+3)->point.y=(
double) (sine*radii.
x*points[2].
x+cosine*radii.
y*
5033 if (i == (ssize_t) (arc_segments-1))
5038 primitive_info->
coordinates=(size_t) (p-primitive_info);
5039 for (i=0; i < (ssize_t) primitive_info->
coordinates; i++)
5047 const size_t number_coordinates)
5073 quantum=number_coordinates;
5074 for (i=0; i < (ssize_t) number_coordinates; i++)
5076 for (j=i+1; j < (ssize_t) number_coordinates; j++)
5078 alpha=fabs(primitive_info[j].point.
x-primitive_info[i].
point.
x);
5079 if (alpha > (
double) quantum)
5080 quantum=(size_t) alpha;
5081 alpha=fabs(primitive_info[j].point.
y-primitive_info[i].
point.
y);
5082 if (alpha > (
double) quantum)
5083 quantum=(size_t) alpha;
5086 quantum=(size_t)
MagickMin((
double) quantum/number_coordinates,
5088 control_points=quantum*number_coordinates;
5090 number_coordinates,
sizeof(*coefficients));
5093 if ((coefficients == (
double *) NULL) || (points == (
PointInfo *) NULL))
5098 end=primitive_info[number_coordinates-1].
point;
5099 for (i=0; i < (ssize_t) number_coordinates; i++)
5100 coefficients[i]=
Permutate((ssize_t) number_coordinates-1,i);
5102 for (i=0; i < (ssize_t) control_points; i++)
5107 alpha=pow((
double) (1.0-weight),(
double) number_coordinates-1.0);
5108 for (j=0; j < (ssize_t) number_coordinates; j++)
5110 point.
x+=alpha*coefficients[j]*p->
point.
x;
5111 point.
y+=alpha*coefficients[j]*p->
point.
y;
5112 alpha*=weight/(1.0-weight);
5116 weight+=1.0/control_points;
5122 for (i=0; i < (ssize_t) control_points; i++)
5129 primitive_info->
coordinates=(size_t) (p-primitive_info);
5130 for (i=0; i < (ssize_t) primitive_info->
coordinates; i++)
5151 alpha=end.
x-start.
x;
5153 radius=hypot((
double) alpha,(
double) beta);
5154 offset.
x=(double) radius;
5155 offset.
y=(double) radius;
5182 if ((stop.
x == 0.0) && (stop.
y == 0.0))
5189 if ((delta >= 0.0) && (delta < (
MagickPI/8.0)))
5193 while (y < degrees.
x)
5196 for (p=primitive_info; angle.
x < angle.
y; angle.
x+=step)
5207 primitive_info->
coordinates=(size_t) (p-primitive_info);
5208 for (i=0; i < (ssize_t) primitive_info->
coordinates; i++)
5227 (primitive_info+1)->primitive=primitive_info->
primitive;
5271 number_coordinates=0;
5273 primitive_type=primitive_info->
primitive;
5275 for (p=path; *p !=
'\0'; )
5277 while (isspace((
int) ((
unsigned char) *p)) != 0)
5281 last_attribute=attribute;
5282 attribute=(int) (*p++);
5331 end.
x=(double) (attribute == (
int)
'A' ? x : point.
x+x);
5332 end.
y=(double) (attribute == (
int)
'A' ? y : point.
y+y);
5336 while (isspace((
int) ((
unsigned char) *p)) != 0)
5352 for (i=1; i < 4; i++)
5362 end.
x=(double) (attribute == (
int)
'C' ? x : point.
x+x);
5363 end.
y=(double) (attribute == (
int)
'C' ? y : point.
y+y);
5366 for (i=0; i < 4; i++)
5367 (q+i)->point=points[i];
5383 point.
x=(double) (attribute == (
int)
'H' ? x: point.
x+x);