93 #define BezierQuantum 200 94 #define PrimitiveExtentPad 2053.0 95 #define MaxBezierCoordinates 67108864 96 #define ThrowPointExpectedException(token,exception) \ 98 (void) ThrowMagickException(exception,GetMagickModule(),DrawError, \ 99 "NonconformingDrawingPrimitiveDefinition","`%s'",token); \ 100 status=MagickFalse; \ 283 if (draw_info->
id != (
char *) NULL)
285 if (draw_info->
primitive != (
char *) NULL)
287 if (draw_info->
geometry != (
char *) NULL)
311 if (draw_info->
text != (
char *) NULL)
313 if (draw_info->
font != (
char *) NULL)
315 if (draw_info->
metrics != (
char *) NULL)
317 if (draw_info->
family != (
char *) NULL)
322 if (draw_info->
encoding != (
char *) NULL)
329 if (draw_info->
density != (
char *) NULL)
346 "UnableToAllocateDashPattern");
347 (void) memset(clone_info->
dash_pattern,0,(
size_t) (2*x+2)*
363 "UnableToAllocateDashPattern");
373 if (draw_info->
clip_mask != (
char *) NULL)
425 for (i=0; i < (ssize_t) polygon_info->
number_edges; i++)
430 polygon_info->
edges);
434 #if defined(__cplusplus) || defined(c_plusplus) 440 #define DrawCompareEdge(p,q) \ 442 if (((p)-(q)) < 0.0) \ 444 if (((p)-(q)) > 0.0) \ 455 p=((
const EdgeInfo *) p_edge)->points;
456 q=((
const EdgeInfo *) q_edge)->points;
466 #if defined(__cplusplus) || defined(c_plusplus) 480 p=polygon_info->
edges;
481 for (i=0; i < (ssize_t) polygon_info->
number_edges; i++)
508 for (i=0; i < (ssize_t) (number_points >> 1); i++)
511 points[i]=points[number_points-(i+1)];
512 points[number_points-(i+1)]=point;
557 sizeof(*polygon_info->
edges));
564 (void) memset(polygon_info->
edges,0,number_edges*
565 sizeof(*polygon_info->
edges));
572 (void) memset(&point,0,
sizeof(point));
573 (void) memset(&bounds,0,
sizeof(bounds));
590 if ((points != (
PointInfo *) NULL) && (n >= 2))
592 if (edge == number_edges)
596 polygon_info->
edges,(
size_t) number_edges,
597 sizeof(*polygon_info->
edges));
635 point=path_info[i].
point;
646 next_direction=((path_info[i].
point.
y > point.
y) ||
648 (path_info[i].point.
x > point.
x))) ? 1 : -1;
649 if ((points != (
PointInfo *) NULL) && (direction != 0) &&
650 (direction != next_direction))
656 if (edge == number_edges)
660 polygon_info->
edges,(
size_t) number_edges,
661 sizeof(*polygon_info->
edges));
699 direction=next_direction;
702 if (n == (ssize_t) number_points)
714 point=path_info[i].
point;
716 if (point.
x < bounds.
x1)
718 if (point.
x > bounds.
x2)
728 if (edge == number_edges)
732 polygon_info->
edges,(
size_t) number_edges,
733 sizeof(*polygon_info->
edges));
767 for (i=0; i < (ssize_t) polygon_info->
number_edges; i++)
772 edge_info=polygon_info->
edges+i;
786 return(polygon_info);
828 "moveto ghostline" : p->
code ==
OpenCode ?
"moveto open" :
892 if (coordinates <= 0)
897 coordinates=(ssize_t) primitive_info[i].coordinates;
898 p=primitive_info[i].
point;
904 if ((code ==
MoveToCode) || (coordinates <= 0) ||
911 path_info[n].
code=code;
913 q=primitive_info[i].
point;
931 path_info[n].
point=p;
968 assert(draw_info != (
DrawInfo *) NULL);
972 if (draw_info->
id != (
char *) NULL)
974 if (draw_info->
primitive != (
char *) NULL)
976 if (draw_info->
text != (
char *) NULL)
978 if (draw_info->
geometry != (
char *) NULL)
984 if (draw_info->
font != (
char *) NULL)
986 if (draw_info->
metrics != (
char *) NULL)
988 if (draw_info->
family != (
char *) NULL)
990 if (draw_info->
encoding != (
char *) NULL)
992 if (draw_info->
density != (
char *) NULL)
1003 if (draw_info->
clip_mask != (
char *) NULL)
1061 inverse_edge.
x1=edge->
x1;
1062 inverse_edge.
y1=edge->
y1;
1063 inverse_edge.
x2=edge->
x2;
1064 inverse_edge.
y2=edge->
y2;
1065 z=affine->
ry*y+affine->
tx;
1068 intercept=(-z/affine->
sx);
1070 if (x > inverse_edge.
x1)
1072 intercept=(-z+(double) image->
columns)/affine->
sx;
1074 if (x < inverse_edge.
x2)
1080 intercept=(-z+(double) image->
columns)/affine->
sx;
1082 if (x > inverse_edge.
x1)
1084 intercept=(-z/affine->
sx);
1086 if (x < inverse_edge.
x2)
1090 if ((z < 0.0) || ((size_t) floor(z+0.5) >= image->
columns))
1092 inverse_edge.
x2=edge->
x1;
1093 return(inverse_edge);
1098 z=affine->
sy*y+affine->
ty;
1101 intercept=(-z/affine->
rx);
1103 if (x > inverse_edge.
x1)
1105 intercept=(-z+(double) image->
rows)/affine->
rx;
1107 if (x < inverse_edge.
x2)
1113 intercept=(-z+(double) image->
rows)/affine->
rx;
1115 if (x > inverse_edge.
x1)
1117 intercept=(-z/affine->
rx);
1119 if (x < inverse_edge.
x2)
1123 if ((z < 0.0) || ((size_t) floor(z+0.5) >= image->
rows))
1125 inverse_edge.
x2=edge->
x2;
1126 return(inverse_edge);
1128 return(inverse_edge);
1141 inverse_affine.
sx=determinant*affine->
sy;
1142 inverse_affine.
rx=determinant*(-affine->
rx);
1143 inverse_affine.
ry=determinant*(-affine->
ry);
1144 inverse_affine.
sy=determinant*affine->
sx;
1145 inverse_affine.
tx=(-affine->
tx)*inverse_affine.
sx-affine->
ty*
1147 inverse_affine.
ty=(-affine->
tx)*inverse_affine.
rx-affine->
ty*
1149 return(inverse_affine);
1187 assert(image != (
Image *) NULL);
1191 assert(source != (
const Image *) NULL);
1196 extent[1].
x=(double) source->
columns-1.0;
1198 extent[2].
x=(
double) source->
columns-1.0;
1199 extent[2].
y=(double) source->
rows-1.0;
1201 extent[3].
y=(
double) source->
rows-1.0;
1202 for (i=0; i < 4; i++)
1208 extent[i].
x=point.
x*affine->
sx+point.
y*affine->
ry+affine->
tx;
1209 extent[i].
y=point.
x*affine->
rx+point.
y*affine->
sy+affine->
ty;
1213 for (i=1; i < 4; i++)
1215 if (min.
x > extent[i].
x)
1217 if (min.
y > extent[i].
y)
1219 if (max.
x < extent[i].
x)
1221 if (max.
y < extent[i].
y)
1240 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1241 #pragma omp parallel for schedule(static) shared(status) \ 1242 magick_number_threads(source,image,stop-start,1) 1244 for (y=start; y <= stop; y++)
1267 inverse_edge=
AffineEdge(source,&inverse_affine,(
double) y,&edge);
1268 if (inverse_edge.
x2 < inverse_edge.
x1)
1272 inverse_edge.
x2+0.5)-ceil(inverse_edge.
x1-0.5)+1),1,exception);
1281 point.
x=(double) x*inverse_affine.
sx+y*inverse_affine.
ry+
1283 point.
y=(
double) x*inverse_affine.
rx+y*inverse_affine.
sy+
1286 point.
x,point.
y,&pixel,exception);
1366 (void) memset(primitive_info,0,
sizeof(primitive_info));
1377 if (clone_info->
density != (
char *) NULL)
1386 resolution.
x=geometry_info.
rho;
1387 resolution.
y=geometry_info.
sigma;
1389 resolution.
y=resolution.
x;
1400 for (i=1; i < (ssize_t) polygon_info->
number_edges; i++)
1412 bounds.
x1=bounds.
x1 < 0.0 ? 0.0 : bounds.
x1 >= (double)
1415 bounds.
y1=bounds.
y1 < 0.0 ? 0.0 : bounds.
y1 >= (double)
1416 image->
rows ? (
double) image->
rows-1 : bounds.
y1;
1418 bounds.
x2=bounds.
x2 < 0.0 ? 0.0 : bounds.
x2 >= (double)
1421 bounds.
y2=bounds.
y2 < 0.0 ? 0.0 : bounds.
y2 >= (double)
1422 image->
rows ? (
double) image->
rows-1 : bounds.
y2;
1423 for (i=0; i < (ssize_t) polygon_info->
number_edges; i++)
1440 coordinates=(ssize_t) primitive_info[0].coordinates;
1442 status=
DrawPrimitive(image,clone_info,primitive_info,exception);
1459 start.
x=(double) (bounds.
x1-mid);
1460 start.
y=(double) (bounds.
y1-mid);
1461 end.
x=(double) (bounds.
x2+mid);
1462 end.
y=(double) (bounds.
y2+mid);
1466 coordinates=(ssize_t) primitive_info[0].coordinates;
1468 status=
DrawPrimitive(image,clone_info,primitive_info,exception);
1515 if (clip_path == (
const char *) NULL)
1519 if (clipping_mask == (
Image *) NULL)
1559 const char *
id,
const char *clip_path,
ExceptionInfo *exception)
1574 assert(image != (
Image *) NULL);
1578 assert(draw_info != (
const DrawInfo *) NULL);
1596 if (clone_info->
clip_mask != (
char *) NULL)
1606 if (separate_mask != (
Image *) NULL)
1609 clip_mask=separate_mask;
1653 const char *
id,
const char *mask_path,
ExceptionInfo *exception)
1668 assert(image != (
Image *) NULL);
1672 assert(draw_info != (
const DrawInfo *) NULL);
1698 if (separate_mask != (
Image *) NULL)
1701 composite_mask=separate_mask;
1710 return(composite_mask);
1777 assert(draw_info != (
const DrawInfo *) NULL);
1781 number_vertices=(size_t) i;
1783 (2UL*number_vertices+32UL),
sizeof(*dash_polygon));
1790 (void) memset(dash_polygon,0,(2UL*number_vertices+32UL)*
1791 sizeof(*dash_polygon));
1794 dash_polygon[0]=primitive_info[0];
1800 for (n=0; offset > 0.0; j=0)
1804 length=scale*(draw_info->
dash_pattern[n]+(n == 0 ? -0.5 : 0.5));
1805 if (offset > length)
1812 if (offset < length)
1824 for (i=1; (i < (ssize_t) number_vertices) && (length >= 0.0); i++)
1826 dx=primitive_info[i].
point.
x-primitive_info[i-1].
point.
x;
1827 dy=primitive_info[i].
point.
y-primitive_info[i-1].
point.
y;
1828 maximum_length=hypot(dx,dy);
1839 for (total_length=0.0; (length >= 0.0) && (maximum_length >= (total_length+length)); )
1841 total_length+=length;
1842 if ((n & 0x01) != 0)
1844 dash_polygon[0]=primitive_info[0];
1845 dash_polygon[0].
point.
x=(double) (primitive_info[i-1].point.x+dx*
1847 dash_polygon[0].
point.
y=(double) (primitive_info[i-1].point.y+dy*
1853 if ((j+1) > (ssize_t) number_vertices)
1855 dash_polygon[j]=primitive_info[i-1];
1856 dash_polygon[j].
point.
x=(double) (primitive_info[i-1].point.x+dx*
1858 dash_polygon[j].
point.
y=(double) (primitive_info[i-1].point.y+dy*
1874 length-=(maximum_length-total_length);
1875 if ((n & 0x01) != 0)
1877 dash_polygon[j]=primitive_info[i];
1881 if ((status !=
MagickFalse) && (total_length < maximum_length) &&
1882 ((n & 0x01) == 0) && (j > 1))
1884 dash_polygon[j]=primitive_info[i-1];
1929 const ssize_t x,
const ssize_t y)
1931 switch (gradient->
type)
1950 p.
x=gradient_vector->
x2-gradient_vector->
x1;
1951 p.
y=gradient_vector->
y2-gradient_vector->
y1;
1952 q.
x=(double) x-gradient_vector->
x1;
1953 q.
y=(
double) y-gradient_vector->
y1;
1954 length=sqrt(q.
x*q.
x+q.
y*q.
y);
1955 gamma=sqrt(p.
x*p.
x+p.
y*p.
y)*length;
1957 scale=p.
x*q.
x+p.
y*q.
y;
1958 offset=gamma*scale*length;
1970 return(sqrt(v.
x*v.
x+v.
y*v.
y));
1978 return(sqrt(v.
x*v.
x+v.
y*v.
y));
2032 assert(image != (
Image *) NULL);
2036 assert(draw_info != (
const DrawInfo *) NULL);
2041 point.
x=gradient_vector->
x2-gradient_vector->
x1;
2042 point.
y=gradient_vector->
y2-gradient_vector->
y1;
2043 length=sqrt(point.
x*point.
x+point.
y*point.
y);
2048 #if defined(MAGICKCORE_OPENMP_SUPPORT) 2049 #pragma omp parallel for schedule(static) shared(status) \ 2050 magick_number_threads(image,image,bounding_box.height-bounding_box.y,1) 2052 for (y=bounding_box.
y; y < (ssize_t) bounding_box.
height; y++)
2085 for (x=bounding_box.
x; x < (ssize_t) bounding_box.
width; x++)
2088 switch (gradient->
spread)
2101 if (offset < gradient->stops[i].offset)
2103 if ((offset < 0.0) || (i == 0))
2106 if ((offset > 1.0) || (i == (ssize_t) gradient->
number_stops))
2130 if ((ssize_t) fmod(offset,2.0) == 0)
2131 offset=fmod(offset,1.0);
2133 offset=1.0-fmod(offset,1.0);
2135 if (offset < gradient->stops[i].offset)
2169 repeat=fmod(offset,length);
2171 repeat=length-fmod(-repeat,length);
2173 repeat=fmod(offset,length);
2174 antialias=(repeat < length) && ((repeat+1.0) > length) ?
2180 repeat=fmod(offset,gradient->
radius);
2182 repeat=gradient->
radius-fmod(-repeat,gradient->
radius);
2184 repeat=fmod(offset,gradient->
radius);
2191 if (offset < gradient->stops[i].offset)
2207 alpha=length-repeat;
2209 alpha=gradient->
radius-repeat;
2277 if (extent <= (
double) *mvg_info->
extent)
2288 *mvg_info->
extent=(size_t) extent;
2289 for (i=mvg_info->
offset+1; i < (ssize_t) extent; i++)
2332 p=(
const char *) target;
2333 q=(
const char *) source;
2334 return(strcmp(p,q));
2355 if (primitive == (
const char *) NULL)
2362 for (q=primitive; *q !=
'\0'; )
2394 for (p=q; *p !=
'\0'; )
2402 end=p-strlen(token)-1;
2407 if ((n == 0) && (end > start))
2445 primitive_info->
point=point;
2452 #define RenderImageTag "Render/Image" 2529 assert(image != (
Image *) NULL);
2533 assert(draw_info != (
DrawInfo *) NULL);
2540 if ((draw_info->
primitive == (
char *) NULL) ||
2554 (*(draw_info->
primitive+1) !=
'-') && (depth == 0))
2558 if (primitive == (
char *) NULL)
2560 primitive_extent=(double) strlen(primitive);
2569 if (graphic_context == (
DrawInfo **) NULL)
2577 sizeof(*primitive_info));
2581 for ( ; n >= 0; n--)
2587 (void) memset(primitive_info,0,(
size_t) number_points*
2588 sizeof(*primitive_info));
2589 (void) memset(&mvg_info,0,
sizeof(mvg_info));
2591 mvg_info.
extent=(&number_points);
2607 for (q=primitive; *q !=
'\0'; )
2614 if (*keyword ==
'\0')
2616 if (*keyword ==
'#')
2621 while ((*q !=
'\n') && (*q !=
'\0'))
2625 p=q-strlen(keyword)-1;
2627 current=graphic_context[n]->
affine;
2641 if (token == next_token)
2647 if (token == next_token)
2653 if (token == next_token)
2659 if (token == next_token)
2665 if (token == next_token)
2671 if (token == next_token)
2700 &graphic_context[n]->border_color,exception);
2723 if ((mvg_class != (
const char *) NULL) && (p > primitive))
2734 offset=(ssize_t) (p-primitive);
2736 elements[offset]=
'\0';
2760 (void)
CloneString(&graphic_context[n]->clip_mask,token);
2762 if (clip_path != (
const char *) NULL)
2764 if (graphic_context[n]->clipping_mask != (
Image *) NULL)
2765 graphic_context[n]->clipping_mask=
2768 graphic_context[n],token,clip_path,exception);
2772 graphic_context[n]->clip_mask);
2773 if (clip_path != (
const char *) NULL)
2775 graphic_context[n]->clip_mask,clip_path);
2777 graphic_context[n]->clip_mask,exception);
2790 if (fill_rule == -1)
2806 if (clip_units == -1)
2874 (void)
CloneString(&graphic_context[n]->density,token);
2885 if (direction == -1)
2905 (void)
CloneString(&graphic_context[n]->encoding,token);
2922 &graphic_context[n]->fill_pattern,exception);
2926 &graphic_context[n]->fill,exception);
2927 if (graphic_context[n]->fill_alpha !=
OpaqueAlpha)
2940 factor=strchr(token,
'%') != (
char *) NULL ? 0.01 : 1.0;
2943 if (token == next_token)
2964 if (fill_rule == -1)
2975 (void)
CloneString(&graphic_context[n]->font,token);
2978 graphic_context[n]->font);
2984 (void)
CloneString(&graphic_context[n]->family,token);
2991 if (token == next_token)
3034 graphic_context[n]->
weight=(size_t) weight;
3090 if (token == next_token)
3099 if (token == next_token)
3113 if (token == next_token)
3134 if (token == next_token)
3159 if (mask_path != (
const char *) NULL)
3161 if (graphic_context[n]->composite_mask != (
Image *) NULL)
3162 graphic_context[n]->composite_mask=
3165 graphic_context[n],token,mask_path,exception);
3168 graphic_context[n]->composite_mask,exception);
3191 factor=strchr(token,
'%') != (
char *) NULL ? 0.01 : 1.0;
3194 if (token == next_token)
3256 DrawError,
"UnbalancedGraphicContextPushPop",
"`%s'",token);
3261 if ((graphic_context[n]->clip_mask != (
char *) NULL) &&
3264 graphic_context[n-1]->clip_mask) != 0)
3294 for (p=q; *q !=
'\0'; )
3300 (void)
GetNextToken(q,(
const char **) NULL,extent,token);
3311 for (p=q; *q !=
'\0'; )
3317 (void)
GetNextToken(q,(
const char **) NULL,extent,token);
3322 if ((q == (
char *) NULL) || (p == (
char *) NULL) || ((q-4) < p))
3353 if (token == next_token)
3359 if (token == next_token)
3365 if (token == next_token)
3371 if (token == next_token)
3379 for (p=q; *q !=
'\0'; )
3385 (void)
GetNextToken(q,(
const char **) NULL,extent,token);
3390 if ((q == (
char *) NULL) || (p == (
char *) NULL) || ((q-4) < p))
3415 "%gx%g%+.15g%+.15g",
3418 bounds.
x1,bounds.
y1);
3427 graphic_context,(
size_t) (n+1),
sizeof(*graphic_context));
3428 if (graphic_context == (
DrawInfo **) NULL)
3436 graphic_context[n-1]);
3440 (void)
CloneString(&graphic_context[n]->
id,token);
3463 if (token == next_token)
3470 if (token == next_token)
3476 token,&next_token)+0.5));
3477 if (token == next_token)
3484 if (token == next_token)
3486 for (p=q; *q !=
'\0'; )
3492 (void)
GetNextToken(q,(
const char **) NULL,extent,token);
3497 if ((q == (
char *) NULL) || (p == (
char *) NULL) || ((q-4) < p))
3508 "%.20gx%.20g%+.20g%+.20g",(
double) bounds.
width,(double)
3509 bounds.
height,(
double) bounds.
x,(double) bounds.
y);
3539 if (token == next_token)
3562 if (token == next_token)
3568 if (token == next_token)
3576 if (token == next_token)
3585 if (token == next_token)
3596 if (number_stops == 1)
3599 if (number_stops > 2)
3612 stops[number_stops-1].
color=stop_color;
3614 factor=strchr(token,
'%') != (
char *) NULL ? 0.01 : 1.0;
3617 if (token == next_token)
3629 &graphic_context[n]->stroke_pattern,exception);
3633 &graphic_context[n]->stroke,exception);
3634 if (graphic_context[n]->stroke_alpha !=
OpaqueAlpha)
3649 if (graphic_context[n]->dash_pattern != (
double *) NULL)
3669 sizeof(*graphic_context[n]->dash_pattern));
3670 if (graphic_context[n]->dash_pattern == (
double *) NULL)
3678 (void) memset(graphic_context[n]->dash_pattern,0,(
size_t)
3679 (2*x+2)*
sizeof(*graphic_context[n]->dash_pattern));
3680 for (j=0; j < x; j++)
3687 if (token == next_token)
3689 if (graphic_context[n]->dash_pattern[j] < 0.0)
3692 if ((x & 0x01) != 0)
3693 for ( ; j < (2*x); j++)
3694 graphic_context[n]->dash_pattern[j]=
3695 graphic_context[n]->dash_pattern[j-x];
3706 if (token == next_token)
3755 factor=strchr(token,
'%') != (
char *) NULL ? 0.01 : 1.0;
3758 if (token == next_token)
3777 if (token == next_token)
3834 &graphic_context[n]->undercolor,exception);
3841 if (token == next_token)
3847 if (token == next_token)
3868 if (use != (
const char *) NULL)
3888 if (token == next_token)
3895 if (token == next_token)
3902 if (token == next_token)
3909 if (token == next_token)
3924 if (token == next_token)
3957 if (number_stops > 1)
3968 if (number_stops > 0)
3982 if (primitive_info[i].text != (
char *) NULL)
3983 primitive_info[i].text=
DestroyString(primitive_info[i].text);
3987 primitive_info[0].
point.
x=0.0;
3988 primitive_info[0].
point.
y=0.0;
3992 for (x=0; *q !=
'\0'; x++)
4001 if (token == next_token)
4007 if (token == next_token)
4009 (void)
GetNextToken(q,(
const char **) NULL,extent,token);
4012 primitive_info[i].
primitive=primitive_type;
4013 primitive_info[i].
point=point;
4019 if (i < (ssize_t) number_points)
4027 if (primitive_info[j].text != (
char *) NULL)
4029 primitive_info[j].
primitive=primitive_type;
4036 bounds.
x1=primitive_info[j].
point.
x;
4037 bounds.
y1=primitive_info[j].
point.
y;
4038 bounds.
x2=primitive_info[j].
point.
x;
4039 bounds.
y2=primitive_info[j].
point.
y;
4040 for (k=1; k < (ssize_t) primitive_info[j].coordinates; k++)
4042 point=primitive_info[j+k].
point;
4043 if (point.
x < bounds.
x1)
4045 if (point.
y < bounds.
y1)
4047 if (point.
x > bounds.
x2)
4049 if (point.
y > bounds.
y2)
4055 coordinates=(double) primitive_info[j].coordinates;
4056 switch (primitive_type)
4070 alpha=bounds.
x2-bounds.
x1;
4071 beta=bounds.
y2-bounds.
y1;
4072 radius=hypot(alpha,beta);
4074 coordinates+=2.0*((size_t) ceil((
double)
MagickPI*radius))+6.0*
4080 coordinates=(
BezierQuantum*(double) primitive_info[j].coordinates);
4092 for (s=token; *s !=
'\0'; s=t)
4106 for (s=token; *s !=
'\0'; s++)
4107 if (strspn(s,
"AaCcQqSsTt") != 0)
4116 if (((
size_t) (i+coordinates)) >= number_points)
4121 number_points+=coordinates+1;
4122 if (number_points < (
size_t) coordinates)
4136 switch (primitive_type)
4141 if (primitive_info[j].coordinates != 1)
4146 status&=
TracePoint(primitive_info+j,primitive_info[j].point);
4147 i=(ssize_t) (j+primitive_info[j].coordinates);
4157 if (primitive_info[j].coordinates != 2)
4162 dx=primitive_info[i].
point.
x-primitive_info[i-1].
point.
x;
4163 dy=primitive_info[i].
point.
y-primitive_info[i-1].
point.
y;
4164 maximum_length=hypot(dx,dy);
4167 status&=
TraceLine(primitive_info+j,primitive_info[j].point,
4168 primitive_info[j+1].point);
4169 i=(ssize_t) (j+primitive_info[j].coordinates);
4174 if (primitive_info[j].coordinates != 2)
4180 primitive_info[j+1].point);
4181 i=(ssize_t) (j+primitive_info[j].coordinates);
4186 if (primitive_info[j].coordinates != 3)
4191 if ((primitive_info[j+2].point.
x < 0.0) ||
4192 (primitive_info[j+2].
point.
y < 0.0))
4197 if ((primitive_info[j+1].point.
x-primitive_info[j].
point.
x) < 0.0)
4202 if ((primitive_info[j+1].point.
y-primitive_info[j].
point.
y) < 0.0)
4208 primitive_info[j+1].point,primitive_info[j+2].point);
4209 i=(ssize_t) (j+primitive_info[j].coordinates);
4214 if (primitive_info[j].coordinates != 3)
4219 status&=
TraceArc(&mvg_info,primitive_info[j].point,
4220 primitive_info[j+1].point,primitive_info[j+2].point);
4221 i=(ssize_t) (j+primitive_info[j].coordinates);
4226 if (primitive_info[j].coordinates != 3)
4231 if ((primitive_info[j+1].point.
x < 0.0) ||
4232 (primitive_info[j+1].
point.
y < 0.0))
4237 status&=
TraceEllipse(&mvg_info,primitive_info[j].point,
4238 primitive_info[j+1].point,primitive_info[j+2].point);
4239 i=(ssize_t) (j+primitive_info[j].coordinates);
4244 if (primitive_info[j].coordinates != 2)
4249 status&=
TraceCircle(&mvg_info,primitive_info[j].point,
4250 primitive_info[j+1].point);
4251 i=(ssize_t) (j+primitive_info[j].coordinates);
4256 if (primitive_info[j].coordinates < 1)
4265 if (primitive_info[j].coordinates < 3)
4270 primitive_info[i]=primitive_info[j];
4279 if (primitive_info[j].coordinates < 3)
4284 status&=
TraceBezier(&mvg_info,primitive_info[j].coordinates);
4285 i=(ssize_t) (j+primitive_info[j].coordinates);
4290 coordinates=(double)
TracePath(&mvg_info,token,exception);
4291 if (coordinates < 0.0)
4296 i=(ssize_t) (j+coordinates);
4305 if (primitive_info[j].coordinates != 1)
4325 if (primitive_info[j].coordinates != 1)
4332 (void)
CloneString(&primitive_info[j].text,token);
4341 primitive_info->
point.
x+=cursor;
4354 cursor+=metrics.
width;
4361 if (primitive_info[j].coordinates != 2)
4367 (void)
CloneString(&primitive_info[j].text,token);
4382 &graphic_context[n]->affine));
4386 graphic_context[n]->stroke_width);
4396 point=primitive_info[i].
point;
4401 point=primitive_info[i].
point;
4402 if (point.
x < graphic_context[n]->
bounds.
x1)
4404 if (point.
y < graphic_context[n]->
bounds.
y1)
4406 if (point.
x > graphic_context[n]->
bounds.
x2)
4408 if (point.
y > graphic_context[n]->
bounds.
y2)
4412 if (i >= (ssize_t) number_points)
4417 if ((n != 0) && (graphic_context[n]->compliance !=
SVGCompliance) &&
4418 (graphic_context[n]->clip_mask != (
char *) NULL) &&
4420 graphic_context[n-1]->clip_mask) != 0))
4426 graphic_context[n]->clip_mask);
4427 if (clip_path != (
const char *) NULL)
4431 graphic_context[n]->clip_mask,exception);
4433 status&=
DrawPrimitive(image,graphic_context[n],primitive_info,
4455 if (primitive_info[i].text != (
char *) NULL)
4462 for ( ; n >= 0; n--)
4529 assert(image != (
Image *) NULL);
4533 assert(draw_info != (
const DrawInfo *) NULL);
4534 assert(name != (
const char *) NULL);
4537 if (path == (
const char *) NULL)
4541 if (geometry == (
const char *) NULL)
4543 if ((*pattern) != (
Image *) NULL)
4550 &(*pattern)->background_color,exception);
4554 "begin pattern-path %s %s",name,geometry);
4562 if (type != (
const char *) NULL)
4614 return(polygon_info);
4634 sizeof(*polygon_info));
4641 (void) memset(polygon_info,0,number_threads*
sizeof(*polygon_info));
4643 if (path_info == (
PathInfo *) NULL)
4652 for (i=1; i < (ssize_t) number_threads; i++)
4661 sizeof(*polygon_info[i]));
4669 edge_info=polygon_info[0]->
edges;
4671 polygon_info[0]->number_edges,
sizeof(*edge_info));
4672 if (polygon_info[i]->edges == (
EdgeInfo *) NULL)
4678 (void) memcpy(polygon_info[i]->edges,edge_info,
4679 polygon_info[0]->number_edges*
sizeof(*edge_info));
4680 for (j=0; j < (ssize_t) polygon_info[i]->number_edges; j++)
4681 polygon_info[i]->edges[j].points=(
PointInfo *) NULL;
4683 for (j=0; j < (ssize_t) polygon_info[i]->number_edges; j++)
4685 edge_info=polygon_info[0]->
edges+j;
4688 if (polygon_info[i]->edges[j].points == (
PointInfo *) NULL)
4694 (void) memcpy(polygon_info[i]->edges[j].points,edge_info->
points,
4699 return(polygon_info);
4709 (
void) memmove(polygon_info->
edges+edge,polygon_info->
edges+edge+1,
4716 const ssize_t y,
double *stroke_alpha)
4745 p=polygon_info->
edges;
4746 for (j=0; j < (ssize_t) polygon_info->
number_edges; j++, p++)
4748 if ((
double) y <= (p->
bounds.
y1-mid-0.5))
4750 if ((
double) y > (p->
bounds.
y2+mid+0.5))
4755 if (((
double) x <= (p->
bounds.
x1-mid-0.5)) ||
4756 ((
double) x > (p->
bounds.
x2+mid+0.5)))
4761 if ((
double) y <= (p->
points[i-1].
y-mid-0.5))
4763 if ((
double) y > (p->
points[i].
y+mid+0.5))
4774 delta.
x=(q+1)->x-q->
x;
4775 delta.
y=(q+1)->y-q->
y;
4776 beta=delta.
x*(x-q->
x)+delta.
y*(y-q->
y);
4779 delta.
x=(double) x-q->
x;
4780 delta.
y=(
double) y-q->
y;
4781 distance=delta.
x*delta.
x+delta.
y*delta.
y;
4785 alpha=delta.
x*delta.
x+delta.
y*delta.
y;
4788 delta.
x=(double) x-(q+1)->x;
4789 delta.
y=(double) y-(q+1)->y;
4790 distance=delta.
x*delta.
x+delta.
y*delta.
y;
4796 distance=alpha*beta*beta;
4806 if ((*stroke_alpha < 1.0) &&
4807 (distance <= ((alpha+0.25)*(alpha+0.25))))
4810 if (distance <= ((alpha+0.25)*(alpha+0.25)))
4816 beta=sqrt((
double) distance);
4818 if (*stroke_alpha < ((alpha-0.25)*(alpha-0.25)))
4819 *stroke_alpha=(alpha-0.25)*(alpha-0.25);
4823 if ((fill ==
MagickFalse) || (distance > 1.0) || (subpath_alpha >= 1.0))
4825 if (distance <= 0.0)
4836 beta=sqrt(distance);
4839 if (subpath_alpha < (alpha*alpha))
4840 subpath_alpha=alpha*alpha;
4848 if (subpath_alpha >= 1.0)
4854 p=polygon_info->
edges;
4855 for (j=0; j < (ssize_t) polygon_info->
number_edges; j++, p++)
4868 if ((
double) y <= p->
points[i].
y)
4871 if ((((q+1)->x-q->
x)*(y-q->
y)) <= (((q+1)->y-q->
y)*(x-q->
x)))
4882 return(subpath_alpha);
4919 assert(image != (
Image *) NULL);
4923 assert(draw_info != (
DrawInfo *) NULL);
4939 bounds=polygon_info[0]->edges[0].bounds;
4943 for (i=1; i < (ssize_t) polygon_info[0]->number_edges; i++)
4945 p=polygon_info[0]->edges+i;
4955 bounds.
x1-=(mid+1.0);
4956 bounds.
y1-=(mid+1.0);
4957 bounds.
x2+=(mid+1.0);
4958 bounds.
y2+=(mid+1.0);
4959 if ((bounds.
x1 >= (
double) image->
columns) ||
4960 (bounds.
y1 >= (
double) image->
rows) ||
4961 (bounds.
x2 <= 0.0) || (bounds.
y2 <= 0.0))
4966 bounds.
x1=bounds.
x1 < 0.0 ? 0.0 : bounds.
x1 >= (double) image->
columns-1.0 ?
4967 (
double) image->
columns-1.0 : bounds.
x1;
4968 bounds.
y1=bounds.
y1 < 0.0 ? 0.0 : bounds.
y1 >= (double) image->
rows-1.0 ?
4969 (
double) image->
rows-1.0 : bounds.
y1;
4970 bounds.
x2=bounds.
x2 < 0.0 ? 0.0 : bounds.
x2 >= (double) image->
columns-1.0 ?
4971 (
double) image->
columns-1.0 : bounds.
x2;
4972 bounds.
y2=bounds.
y2 < 0.0 ? 0.0 : bounds.
y2 >= (double) image->
rows-1.0 ?
4973 (
double) image->
rows-1.0 : bounds.
y2;
4977 (polygon_info[0]->number_edges == 0))
4984 #if defined(MAGICKCORE_OPENMP_SUPPORT) 4985 #pragma omp parallel for schedule(static) shared(status) \ 4986 magick_number_threads(image,image,stop_y-start_y+1,1) 4988 for (y=start_y; y <= stop_y; y++)
5019 for ( ; x <= stop_x; x++)
5024 GetFillColor(draw_info,x-start_x,y-start_y,&pixel,exception);
5037 " end draw-polygon");
5045 #if defined(MAGICKCORE_OPENMP_SUPPORT) 5046 #pragma omp parallel for schedule(static) shared(status) \ 5047 magick_number_threads(image,image,stop_y-start_y+1,1) 5049 for (y=start_y; y <= stop_y; y++)
5075 for (x=start_x; x <= stop_x; x++)
5092 fill_alpha=fill_alpha > 0.5 ? 1.0 : 0.0;
5093 stroke_alpha=stroke_alpha > 0.5 ? 1.0 : 0.0;
5095 GetFillColor(draw_info,x-start_x,y-start_y,&fill_color,exception);
5098 GetStrokeColor(draw_info,x-start_x,y-start_y,&stroke_color,exception);
5175 "AlphaPrimitive %.20g,%.20g %s",(double) x,(
double) y,
5176 methods[primitive_info->
method]);
5182 "ColorPrimitive %.20g,%.20g %s",(double) x,(
double) y,
5183 methods[primitive_info->
method]);
5189 "ImagePrimitive %.20g,%.20g",(double) x,(
double) y);
5195 "PointPrimitive %.20g,%.20g %s",(double) x,(
double) y,
5196 methods[primitive_info->
method]);
5202 "TextPrimitive %.20g,%.20g",(double) x,(
double) y);
5209 p=primitive_info[0].
point;
5214 point=primitive_info[i].
point;
5215 if (coordinates <= 0)
5217 coordinates=(ssize_t) primitive_info[i].coordinates;
5219 " begin open (%.20g)",(double) coordinates);
5222 point=primitive_info[i].
point;
5226 " %.20g: %.18g,%.18g",(double) coordinates,point.
x,point.
y);
5229 " %.20g: %g %g (duplicate)",(
double) coordinates,point.
x,point.
y);
5232 if (coordinates > 0)
5237 (double) coordinates);
5240 (
double) coordinates);
5264 " begin draw-primitive");
5266 " affine: %g,%g,%g,%g,%g,%g",draw_info->
affine.
sx,
5291 switch (primitive_info->
method)
5319 for (y=0; y < (ssize_t) image->
rows; y++)
5328 for (x=0; x < (ssize_t) image->
columns; x++)
5375 for (y=0; y < (ssize_t) image->
rows; y++)
5384 for (x=0; x < (ssize_t) image->
columns; x++)
5401 switch (primitive_info->
method)
5429 for (y=0; y < (ssize_t) image->
rows; y++)
5438 for (x=0; x < (ssize_t) image->
columns; x++)