forked from enlightenment/efl
evas map: remove redundant code.
Remove old anti-alias code since high quality map is replaced with new one. New anti-aliasing is logically same but having a regression bug, it should be stablized.
This commit is contained in:
parent
84e162b01f
commit
d5551bdda3
|
@ -84,8 +84,6 @@ _interpolated_clip_span(Span *s, int c1, int c2, Eina_Bool interp_col)
|
|||
}
|
||||
}
|
||||
|
||||
#include "evas_map_image_aa.c"
|
||||
|
||||
// 12.63 % of time - this can improve
|
||||
static void
|
||||
_calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy EINA_UNUSED, int cw, int ch EINA_UNUSED)
|
||||
|
@ -861,14 +859,18 @@ evas_common_map_thread_rgba_cb(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Conte
|
|||
EAPI void
|
||||
evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst,
|
||||
RGBA_Draw_Context *dc,
|
||||
int npoints EINA_UNUSED, RGBA_Map_Point *p,
|
||||
int npoints, RGBA_Map_Point *p,
|
||||
int smooth, int level)
|
||||
{
|
||||
Evas_Common_Map_RGBA_Cb cb;
|
||||
|
||||
if (dc->anti_alias && smooth)
|
||||
{
|
||||
//FIXME: we cannot apply anti_aliasing per polygons.
|
||||
Eina_Bool aa = dc->anti_alias;
|
||||
if (npoints > 4) dc->anti_alias = EINA_FALSE;
|
||||
cb = evas_common_map_rgba_internal_high;
|
||||
if (npoints > 4) dc->anti_alias = aa;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -892,11 +894,13 @@ evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst,
|
|||
}
|
||||
|
||||
EAPI void
|
||||
evas_common_map_rgba_draw(RGBA_Image *src, RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 mul_col, int render_op, int npoints EINA_UNUSED, RGBA_Map_Point *p, int smooth, Eina_Bool anti_alias, int level, RGBA_Image *mask_ie, int mask_x, int mask_y)
|
||||
evas_common_map_rgba_draw(RGBA_Image *src, RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 mul_col, int render_op, int npoints, RGBA_Map_Point *p, int smooth, Eina_Bool anti_alias, int level, RGBA_Image *mask_ie, int mask_x, int mask_y)
|
||||
{
|
||||
//The best quaility requsted.
|
||||
if (anti_alias && smooth)
|
||||
{
|
||||
//FIXME: we cannot apply anti_aliasing per polygons.
|
||||
if (npoints > 4) anti_alias = EINA_FALSE;
|
||||
_evas_common_map_rgba_internal_high(src, dst,
|
||||
clip_x, clip_y, clip_w, clip_h,
|
||||
mul_col, render_op,
|
||||
|
|
|
@ -1,254 +0,0 @@
|
|||
#define PUSH_EDGE_POINT() \
|
||||
do \
|
||||
{ \
|
||||
p_edge.x = spans[y].span[0].x[eidx]; \
|
||||
p_edge.y = y; \
|
||||
ptx[0] = tx[0]; \
|
||||
ptx[1] = tx[1]; \
|
||||
} while (0)
|
||||
|
||||
static void
|
||||
calc_irregular_coverage(Line* spans, int eidx, int y, int diagonal,
|
||||
int edge_dist, Eina_Bool reverse)
|
||||
{
|
||||
if (eidx == 1) reverse = !reverse;
|
||||
int coverage = (255 / (diagonal + 2));
|
||||
int tmp;
|
||||
for (int ry = 0; ry < (diagonal + 2); ry++)
|
||||
{
|
||||
tmp = y - ry - edge_dist;
|
||||
if (tmp < 0) return;
|
||||
spans[tmp].aa_len[eidx] = 1;
|
||||
if (reverse) spans[tmp].aa_cov[eidx] = 255 - (coverage * ry);
|
||||
else spans[tmp].aa_cov[eidx] = (coverage * ry);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
calc_vert_coverage(Line *spans, int eidx, int y, int rewind, Eina_Bool reverse)
|
||||
{
|
||||
if (eidx == 1) reverse = !reverse;
|
||||
int coverage = (255 / (rewind + 1));
|
||||
int tmp;
|
||||
for (int ry = 1; ry < (rewind + 1); ry++)
|
||||
{
|
||||
tmp = y - ry;
|
||||
if (tmp < 0 ) return;
|
||||
spans[tmp].aa_len[eidx] = 1;
|
||||
if (reverse) spans[tmp].aa_cov[eidx] = (255 - (coverage * ry));
|
||||
else spans[tmp].aa_cov[eidx] = (coverage * ry);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
calc_horiz_coverage(Line *spans, int eidx, int y, int x, int x2)
|
||||
{
|
||||
if (spans[y].aa_len[eidx] < abs(x - x2))
|
||||
{
|
||||
spans[y].aa_len[eidx] = abs(x - x2);
|
||||
spans[y].aa_cov[eidx] = (255 / (spans[y].aa_len[eidx] + 1));
|
||||
}
|
||||
}
|
||||
|
||||
static inline DATA32
|
||||
_aa_coverage_apply(Line *line, int ww, int w, DATA32 val, Eina_Bool src_alpha)
|
||||
{
|
||||
//Left Edge Anti Anliasing
|
||||
if ((w - line->aa_len[0]) < ww)
|
||||
{
|
||||
return MUL_256((line->aa_cov[0] * (w - ww + 1)), val);
|
||||
}
|
||||
//Right Edge Anti Aliasing
|
||||
if (line->aa_len[1] >= ww)
|
||||
{
|
||||
return MUL_256(255 - (line->aa_cov[1] * (line->aa_len[1] - ww + 1)),
|
||||
val);
|
||||
}
|
||||
//Remove Transparency if src image alpha is off.
|
||||
if (!src_alpha)
|
||||
{
|
||||
if (((val & 0xff000000) >> 24) < 0xff)
|
||||
return (val | 0xff000000);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* To understand here AA main logic,
|
||||
* Please refer this page: hermet.pe.kr/122?catgory=662934
|
||||
*/
|
||||
static void
|
||||
_calc_aa_edges_internal(Line *spans, int eidx, int ystart, int yend)
|
||||
{
|
||||
int y;
|
||||
Evas_Coord_Point p_edge = {-1, -1}; //previous edge point
|
||||
Evas_Coord_Point edge_diff = {0, 0}; //temporary used for point distance
|
||||
|
||||
/* store bigger to tx[0] between prev and current edge's x positions. */
|
||||
int tx[2] = {0, 0};
|
||||
/* back up prev tx values */
|
||||
int ptx[2] = {0, 0};
|
||||
int diagonal = 0; //straight diagonal pixels counti
|
||||
|
||||
//Previous edge direction:
|
||||
#define DirOutHor 0x0011
|
||||
#define DirOutVer 0x0001
|
||||
#define DirInHor 0x0010
|
||||
#define DirInVer 0x0000
|
||||
#define DirNone 0x1000
|
||||
|
||||
int prev_dir = DirNone;
|
||||
int cur_dir = DirNone;
|
||||
|
||||
yend -= ystart;
|
||||
|
||||
//Find Start Edge
|
||||
for (y = 0; y < yend; y++)
|
||||
{
|
||||
if (spans[y].span[0].x[0] == -1) continue;
|
||||
p_edge.x = spans[y].span[0].x[eidx];
|
||||
p_edge.y = y;
|
||||
break;
|
||||
}
|
||||
|
||||
//Calculates AA Edges
|
||||
for (y++; y < yend; y++)
|
||||
{
|
||||
//Ready tx
|
||||
if (eidx == 0)
|
||||
{
|
||||
tx[0] = p_edge.x;
|
||||
tx[1] = spans[y].span[0].x[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
tx[0] = spans[y].span[0].x[1];
|
||||
tx[1] = p_edge.x;
|
||||
}
|
||||
|
||||
edge_diff.x = (tx[0] - tx[1]);
|
||||
edge_diff.y = (y - p_edge.y);
|
||||
|
||||
//Confirm current edge direction
|
||||
if (edge_diff.x > 0)
|
||||
{
|
||||
if (edge_diff.y == 1) cur_dir = DirOutHor;
|
||||
else cur_dir = DirOutVer;
|
||||
}
|
||||
else if (edge_diff.x < 0)
|
||||
{
|
||||
if (edge_diff.y == 1) cur_dir = DirInHor;
|
||||
else cur_dir = DirInVer;
|
||||
}
|
||||
else cur_dir = DirNone;
|
||||
|
||||
//straight diagonal increase
|
||||
if ((cur_dir == prev_dir) && (y < yend))
|
||||
{
|
||||
if ((abs(edge_diff.x) == 1) && (edge_diff.y == 1))
|
||||
{
|
||||
++diagonal;
|
||||
PUSH_EDGE_POINT();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
switch (cur_dir)
|
||||
{
|
||||
case DirOutHor:
|
||||
{
|
||||
calc_horiz_coverage(spans, eidx, y, tx[0], tx[1]);
|
||||
if (diagonal > 0)
|
||||
{
|
||||
calc_irregular_coverage(spans, eidx, y, diagonal, 0,
|
||||
EINA_TRUE);
|
||||
diagonal = 0;
|
||||
}
|
||||
/* Increment direction is changed:
|
||||
Outside Vertical -> Outside Horizontal */
|
||||
if (prev_dir == DirOutVer)
|
||||
calc_horiz_coverage(spans, eidx, p_edge.y, ptx[0], ptx[1]);
|
||||
|
||||
//Tricky case by fine tuning.
|
||||
if (y == 1)
|
||||
calc_horiz_coverage(spans, eidx, p_edge.y, tx[0], tx[1]);
|
||||
|
||||
PUSH_EDGE_POINT();
|
||||
}
|
||||
break;
|
||||
case DirOutVer:
|
||||
{
|
||||
calc_vert_coverage(spans, eidx, y, edge_diff.y, EINA_TRUE);
|
||||
if (diagonal > 0)
|
||||
{
|
||||
calc_irregular_coverage(spans, eidx, y, diagonal,
|
||||
edge_diff.y, EINA_FALSE);
|
||||
diagonal = 0;
|
||||
}
|
||||
/* Increment direction is changed:
|
||||
Outside Horizontal -> Outside Vertical */
|
||||
if (prev_dir == DirOutHor)
|
||||
calc_horiz_coverage(spans, eidx, p_edge.y, ptx[0], ptx[1]);
|
||||
PUSH_EDGE_POINT();
|
||||
}
|
||||
break;
|
||||
case DirInHor:
|
||||
{
|
||||
calc_horiz_coverage(spans, eidx, (y - 1), tx[0], tx[1]);
|
||||
if (diagonal > 0)
|
||||
{
|
||||
calc_irregular_coverage(spans, eidx, y, diagonal, 0,
|
||||
EINA_FALSE);
|
||||
diagonal = 0;
|
||||
}
|
||||
/* Increment direction is changed:
|
||||
Outside Horizontal -> Inside Horizontal */
|
||||
if (prev_dir == DirOutHor)
|
||||
calc_horiz_coverage(spans, eidx, p_edge.y, ptx[0], ptx[1]);
|
||||
PUSH_EDGE_POINT();
|
||||
}
|
||||
break;
|
||||
case DirInVer:
|
||||
{
|
||||
calc_vert_coverage(spans, eidx, y, edge_diff.y, EINA_FALSE);
|
||||
if (diagonal > 0)
|
||||
{
|
||||
calc_irregular_coverage(spans, eidx, y, diagonal,
|
||||
edge_diff.y, EINA_TRUE);
|
||||
diagonal = 0;
|
||||
}
|
||||
/* Increment direction is changed:
|
||||
Outside Horizontal -> Inside Vertical */
|
||||
if (prev_dir == DirOutHor)
|
||||
calc_horiz_coverage(spans, eidx, p_edge.y, ptx[0], ptx[1]);
|
||||
PUSH_EDGE_POINT();
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (cur_dir != DirNone) prev_dir = cur_dir;
|
||||
}
|
||||
|
||||
//leftovers...?
|
||||
if ((edge_diff.y == 1) && (edge_diff.x != 0))
|
||||
{
|
||||
calc_horiz_coverage(spans, eidx, y - 1, ptx[0], ptx[1]);
|
||||
calc_horiz_coverage(spans, eidx, y, tx[0], tx[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
++y;
|
||||
if (y > yend) y = yend;
|
||||
calc_vert_coverage(spans, eidx, y, (edge_diff.y + 2),
|
||||
(prev_dir & 0x00000001));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_calc_aa_edges(Line *spans, int ystart, int yend)
|
||||
{
|
||||
//FIXME: support 2 span case.
|
||||
|
||||
//left side
|
||||
_calc_aa_edges_internal(spans, 0, ystart, yend);
|
||||
//right side
|
||||
_calc_aa_edges_internal(spans, 1, ystart, yend);
|
||||
}
|
|
@ -5,7 +5,7 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst,
|
|||
int clip_x, int clip_y, int clip_w, int clip_h,
|
||||
DATA32 mul_col, int render_op,
|
||||
RGBA_Map_Point *p,
|
||||
int smooth, int anti_alias, int level EINA_UNUSED, // level unused for now - for future use
|
||||
int smooth, int anti_alias EINA_UNUSED, int level EINA_UNUSED, // level unused for now - for future use
|
||||
RGBA_Image *mask_ie, int mask_x, int mask_y)
|
||||
{
|
||||
int i;
|
||||
|
@ -84,9 +84,6 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst,
|
|||
// calculate the spans list
|
||||
_calc_spans(p, spans, ystart, yend, cx, cy, cw, ch);
|
||||
|
||||
// calculate anti alias edges
|
||||
if (anti_alias) _calc_aa_edges(spans, ystart, yend);
|
||||
|
||||
// walk through spans and render
|
||||
|
||||
// if operation is solid, bypass buf and draw func and draw direct to dst
|
||||
|
@ -97,7 +94,7 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst,
|
|||
pixels composition. we can optimize it. */
|
||||
|
||||
if ((!sa) && (!da) &&
|
||||
(mul_col == 0xffffffff) && (!havea) && (!anti_alias) && (!mask_ie))
|
||||
(mul_col == 0xffffffff) && (!havea) && (!mask_ie))
|
||||
{
|
||||
direct = 1;
|
||||
}
|
||||
|
@ -106,7 +103,7 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst,
|
|||
buf = alloca(cw * sizeof(DATA32));
|
||||
if (havea) sa = EINA_TRUE;
|
||||
|
||||
saa = (anti_alias | sa);
|
||||
saa = sa;
|
||||
|
||||
if (!mask_ie)
|
||||
{
|
||||
|
@ -139,7 +136,7 @@ static void
|
|||
FUNC_NAME_DO(RGBA_Image *src, RGBA_Image *dst,
|
||||
RGBA_Draw_Context *dc,
|
||||
const RGBA_Map_Spans *ms,
|
||||
int smooth, int anti_alias, int level EINA_UNUSED) // level unused for now - for future use
|
||||
int smooth, int anti_alias EINA_UNUSED, int level EINA_UNUSED) // level unused for now - for future use
|
||||
{
|
||||
Line *spans;
|
||||
DATA32 *buf = NULL, *sp;
|
||||
|
@ -192,7 +189,7 @@ FUNC_NAME_DO(RGBA_Image *src, RGBA_Image *dst,
|
|||
buf = alloca(cw * sizeof(DATA32));
|
||||
if (ms->havea) sa = EINA_TRUE;
|
||||
|
||||
saa = (anti_alias | sa);
|
||||
saa = sa;
|
||||
|
||||
if (!mask_ie)
|
||||
{
|
||||
|
|
|
@ -335,162 +335,6 @@ _map_aa_apply(AASpans *aa_spans, DATA32 *dst, int dw)
|
|||
}
|
||||
|
||||
/************************** TEXTURE MAPPING CODE ******************************/
|
||||
|
||||
#if 0 //We only use biliear(smooth) mapping logic right now.
|
||||
static void
|
||||
_map_triangle_draw_point(RGBA_Image *src, RGBA_Image *dst,
|
||||
int cx, int cy, int cw, int ch,
|
||||
RGBA_Image *mask, int mx, int my,
|
||||
int ystart, int yend,
|
||||
DATA32 *tbuf, RGBA_Gfx_Func func, RGBA_Gfx_Func func2,
|
||||
DATA32 mul_col, AASpans *aa_spans,
|
||||
Eina_Bool col_blend)
|
||||
{
|
||||
float _dudx = dudx, _dvdx = dvdx;
|
||||
float _dxdya = dxdya, _dxdyb = dxdyb, _dudya = dudya, _dvdya = dvdya;
|
||||
float _xa = xa, _xb = xb, _ua = ua, _va = va;
|
||||
DATA32 *sbuf = src->image.data;
|
||||
DATA32 *dbuf = dst->image.data;
|
||||
int sw = src->cache_entry.w;
|
||||
int sh = src->cache_entry.h;
|
||||
int dw = dst->cache_entry.w;
|
||||
int x, y, x1, x2, uu, vv, ay;
|
||||
float dx, u, v;
|
||||
float _dcdx[4], _dcdya[4], _ca[4], c[4];
|
||||
DATA32 *buf, *tmp;
|
||||
DATA8 *mbuf;
|
||||
|
||||
//Range exception handling
|
||||
if (ystart >= (cy + ch)) return;
|
||||
if (ystart < cy) ystart = cy;
|
||||
if (yend > (cy + ch)) yend = (cy + ch);
|
||||
|
||||
if (col_blend)
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
_dcdx[i] = dcdx[i];
|
||||
_dcdya[i] = dcdya[i];
|
||||
_ca[i] = ca[i];
|
||||
}
|
||||
|
||||
//Loop through all lines in the segment
|
||||
y = ystart;
|
||||
|
||||
while (y < yend)
|
||||
{
|
||||
x1 = _xa;
|
||||
x2 = _xb;
|
||||
|
||||
//Range exception handling
|
||||
//OPTIMIZE ME, handle in advance?
|
||||
if (x1 < cx) x1 = cx;
|
||||
if (x2 > (cx + cw)) x2 = (cx + cw);
|
||||
|
||||
if (aa_spans)
|
||||
{
|
||||
ay = y - aa_spans->ystart;
|
||||
if (aa_spans->lines[ay].x[0] > x1) aa_spans->lines[ay].x[0] = x1;
|
||||
if (aa_spans->lines[ay].x[1] < x2) aa_spans->lines[ay].x[1] = x2;
|
||||
}
|
||||
|
||||
if ((x2 - x1) < 1) goto next;
|
||||
|
||||
//Perform subtexel pre-stepping on UV
|
||||
dx = 1 - (_xa - x1);
|
||||
u = _ua + dx * _dudx;
|
||||
v = _va + dx * _dvdx;
|
||||
if (col_blend)
|
||||
{
|
||||
c[0] = _ca[0] + dx * _dcdx[0];
|
||||
c[1] = _ca[1] + dx * _dcdx[1];
|
||||
c[2] = _ca[2] + dx * _dcdx[2];
|
||||
c[3] = _ca[3] + dx * _dcdx[3];
|
||||
}
|
||||
|
||||
//Direct draw or blending intervention?
|
||||
if (tbuf) buf = tbuf;
|
||||
else buf = dbuf + ((y * dw) + x1);
|
||||
|
||||
x = x1;
|
||||
|
||||
//Draw horizontal line
|
||||
while (x++ < x2)
|
||||
{
|
||||
uu = (int) u;
|
||||
vv = (int) v;
|
||||
|
||||
//Range exception handling
|
||||
//FIXME: handle in advance?
|
||||
if (uu >= sw) uu = sw - 1;
|
||||
if (vv >= sh) vv = sh - 1;
|
||||
|
||||
//Copy pixel from texture to screen
|
||||
if (!col_blend)
|
||||
{
|
||||
*(buf) = sbuf[(vv * sw) + uu];
|
||||
}
|
||||
//Vertex Color Blending
|
||||
else
|
||||
{
|
||||
DATA32 tmp = (((int) c[0]) << 24) | (((int) c[1]) << 16) | (((int) c[2]) << 8) | ((int) c[3]);
|
||||
*buf = MUL4_SYM(tmp, sbuf[(vv * sw) + uu]);
|
||||
c[0] += _dcdx[0];
|
||||
c[1] += _dcdx[1];
|
||||
c[2] += _dcdx[2];
|
||||
c[3] += _dcdx[3];
|
||||
}
|
||||
|
||||
//Step UV horizontally
|
||||
u += _dudx;
|
||||
v += _dvdx;
|
||||
++buf;
|
||||
}
|
||||
if (tbuf)
|
||||
{
|
||||
tmp = dbuf + ((y * dw) + x1);
|
||||
int len = x2 - x1;
|
||||
if (!mask) func(tbuf, NULL, mul_col, tmp, len);
|
||||
else
|
||||
{
|
||||
mbuf = mask->image.data8
|
||||
+ (y - my) * mask->cache_entry.w + (x1 - mx);
|
||||
if (mul_col != 0xffffffff)
|
||||
func2(tbuf, NULL, mul_col, tbuf, len);
|
||||
func(tbuf, mbuf, 0, tmp, len);
|
||||
}
|
||||
}
|
||||
next:
|
||||
//Step along both edges
|
||||
_xa += _dxdya;
|
||||
_xb += _dxdyb;
|
||||
_ua += _dudya;
|
||||
_va += _dvdya;
|
||||
|
||||
if (col_blend)
|
||||
{
|
||||
_ca[0] += _dcdya[0];
|
||||
_ca[1] += _dcdya[1];
|
||||
_ca[2] += _dcdya[2];
|
||||
_ca[3] += _dcdya[3];
|
||||
}
|
||||
|
||||
y++;
|
||||
}
|
||||
xa = _xa;
|
||||
xb = _xb;
|
||||
ua = _ua;
|
||||
va = _va;
|
||||
|
||||
if (col_blend)
|
||||
{
|
||||
ca[0] = _ca[0];
|
||||
ca[1] = _ca[1];
|
||||
ca[2] = _ca[2];
|
||||
ca[3] = _ca[3];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
_map_triangle_draw_linear(RGBA_Image *src, RGBA_Image *dst,
|
||||
int cx, int cy, int cw, int ch,
|
||||
|
@ -920,11 +764,6 @@ _evas_common_map_rgba_internal_high(RGBA_Image *src, RGBA_Image *dst,
|
|||
Eina_Bool dst_alpha = dst->cache_entry.flags.alpha;
|
||||
Eina_Bool col_blend = EINA_FALSE; //Necessary blending vertex color?
|
||||
|
||||
/* FIXME: efl_ui_textpath should not use anti-aliasing.
|
||||
If we have a proper method to select this function optionally,
|
||||
we can enable AA then. */
|
||||
anti_alias = EINA_FALSE;
|
||||
|
||||
/* Prepare points data.
|
||||
Convert to float,
|
||||
shift XY coordinates to match the sub-pixeling technique.
|
||||
|
|
|
@ -237,7 +237,6 @@
|
|||
u += ud;
|
||||
v += vd;
|
||||
# endif //COLBLACK
|
||||
if (anti_alias) *d = _aa_coverage_apply(line, ww, w, *d, sa);
|
||||
d++;
|
||||
ww--;
|
||||
}
|
||||
|
@ -359,7 +358,6 @@
|
|||
u += ud;
|
||||
v += vd;
|
||||
# endif //COLBLACK
|
||||
if (anti_alias) *d = _aa_coverage_apply(line, ww, w, *d, sa);
|
||||
d++;
|
||||
ww--;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue