34#define FASTEDGELENGTH 256
36static BOOL_VAR(poly_debug,
false,
"Debug old poly");
37static BOOL_VAR(poly_wide_objects_better,
true,
38 "More accurate approx on wide things");
73 if (vecsum.
x == 0 && vecsum.
y == 0) {
79 vlen = vecsum.
x > 0 ? vecsum.
x : -vecsum.
x;
80 if (vecsum.
y > vlen) {
82 }
else if (-vecsum.
y > vlen) {
89 squaresum = ptcount = 0;
93 perp = vec.
cross(vecsum);
100 tprintf(
"Cutline:Final perp=%d\n", perp);
102 if (perp > maxperp) {
106 vec.
x += edge->
vec.
x;
107 vec.
y += edge->
vec.
y;
109 }
while (edge !=
last);
114 if (maxperp < 256 * INT16_MAX) {
121 if (squaresum < 256 * INT16_MAX) {
123 perp = (squaresum << 8) / (perp * ptcount);
126 perp = (squaresum / perp << 8) / ptcount;
130 tprintf(
"Cutline:A=%d, max=%.2f(%.2f%%), msd=%.2f(%.2f%%)\n", area,
131 maxperp / 256.0, maxperp * 200.0 / area, perp / 256.0,
132 perp * 300.0 / area);
134 if (maxperp *
par1 >= 10 * area || perp *
par2 >= 10 * area || vlen >= 126) {
135 maxpoint->
fixed =
true;
137 cutline(first, maxpoint, area);
138 cutline(maxpoint,
last, area);
148static EDGEPT *edgesteps_to_edgepts(
149 C_OUTLINE *c_outline,
163 pos = c_outline->start_pos();
164 length = c_outline->pathlength();
170 int prev_stepindex = 0;
172 dir = c_outline->step_dir(stepindex);
173 vec = c_outline->step(stepindex);
174 if (stepindex < length - 1 &&
175 c_outline->step_dir(stepindex + 1) - dir == -32) {
177 vec += c_outline->step(stepindex + 1);
186 if (prevdir.get_dir() != dir.get_dir()) {
187 edgepts[epindex].pos.x = pos.x();
188 edgepts[epindex].pos.y = pos.y();
190 edgepts[epindex].vec.x = prev_vec.x();
191 edgepts[epindex].vec.y = prev_vec.y();
193 edgepts[epindex].runlength =
count;
194 edgepts[epindex].prev = &edgepts[epindex - 1];
196 edgepts[epindex].fixed =
false;
197 edgepts[epindex].next = &edgepts[epindex + 1];
199 epdir = DIR128(0) - prevdir;
202 edgepts[epindex].dir = epdir;
203 edgepts[epindex].src_outline = c_outline;
204 edgepts[epindex].start_step = prev_stepindex;
205 edgepts[epindex].step_count = stepindex - prev_stepindex;
210 prev_stepindex = stepindex;
214 stepindex += stepinc;
215 }
while (stepindex < length);
216 edgepts[epindex].pos.x = pos.x();
217 edgepts[epindex].pos.y = pos.y();
219 edgepts[epindex].vec.x = prev_vec.x();
220 edgepts[epindex].vec.y = prev_vec.y();
222 edgepts[epindex].runlength =
count;
224 edgepts[epindex].fixed =
false;
225 edgepts[epindex].src_outline = c_outline;
226 edgepts[epindex].start_step = prev_stepindex;
227 edgepts[epindex].step_count = stepindex - prev_stepindex;
228 edgepts[epindex].prev = &edgepts[epindex - 1];
229 edgepts[epindex].next = &edgepts[0];
231 epdir = DIR128(0) - prevdir;
234 edgepts[epindex].dir = epdir;
235 edgepts[0].prev = &edgepts[epindex];
236 ASSERT_HOST(pos.x() == c_outline->start_pos().x() &&
237 pos.y() == c_outline->start_pos().y());
254 int d01, d12, d23, gapmin;
255 TPOINT d01vec, d12vec, d23vec;
256 EDGEPT *edgefix, *startfix;
257 EDGEPT *edgefix0, *edgefix1, *edgefix2, *edgefix3;
260 while (((edgept->dir - edgept->prev->dir + 1) & 7) < 3 &&
261 (dir = (edgept->prev->dir - edgept->next->dir) & 7) != 2 && dir != 6) {
262 edgept = edgept->next;
267 bool stopped =
false;
268 edgept->fixed =
true;
271 auto dir1 = edgept->dir;
273 auto sum1 = edgept->runlength;
274 edgept = edgept->next;
275 auto dir2 = edgept->dir;
277 auto sum2 = edgept->runlength;
278 if (((dir1 - dir2 + 1) & 7) < 3) {
279 while (edgept->prev->dir == edgept->next->dir) {
280 edgept = edgept->next;
281 if (edgept->dir == dir1) {
283 sum1 += edgept->runlength;
285 sum2 += edgept->runlength;
289 if (edgept == loopstart) {
293 if (sum2 + sum1 > 2 && linestart->prev->dir == dir2 &&
294 (linestart->prev->runlength > linestart->runlength || sum2 > sum1)) {
296 linestart = linestart->prev;
297 linestart->fixed =
true;
300 if (((edgept->next->dir - edgept->dir + 1) & 7) >= 3 ||
301 (edgept->dir == dir1 && sum1 >= sum2) ||
302 ((edgept->prev->runlength < edgept->runlength ||
303 (edgept->dir == dir2 && sum2 >= sum1)) &&
304 linestart->next != edgept)) {
305 edgept = edgept->next;
309 edgept->fixed =
true;
312 while (edgept != loopstart && !stopped);
316 if (((edgept->runlength >= 8) && (edgept->dir != 2) &&
317 (edgept->dir != 6)) ||
318 ((edgept->runlength >= 8) &&
319 ((edgept->dir == 2) || (edgept->dir == 6)))) {
320 edgept->fixed =
true;
321 edgept1 = edgept->next;
322 edgept1->fixed =
true;
324 edgept = edgept->next;
325 }
while (edgept != start);
331 edgept->runlength == 1
333 && edgept->next->fixed &&
336 && !edgept->next->next->fixed &&
337 edgept->prev->dir == edgept->next->dir &&
338 edgept->prev->prev->dir == edgept->next->next->dir &&
339 ((edgept->prev->dir - edgept->dir + 1) & 7) < 3) {
341 edgept->fixed =
false;
342 edgept->next->fixed =
false;
344 edgept = edgept->next;
345 }
while (edgept != start);
360 edgept = edgept->next;
361 }
while (edgept != start);
362 while (!edgept->fixed) {
363 edgept = edgept->next;
367 edgept = edgept->next;
368 while (!edgept->fixed) {
369 edgept = edgept->next;
373 edgept = edgept->next;
374 while (!edgept->fixed) {
375 edgept = edgept->next;
379 edgept = edgept->next;
380 while (!edgept->fixed) {
381 edgept = edgept->next;
388 if (fixed_count <= 3) {
391 d12vec.diff(edgefix1->pos, edgefix2->pos);
392 d12 = d12vec.length();
399 d01vec.diff(edgefix0->pos, edgefix1->pos);
400 d01 = d01vec.length();
401 d23vec.diff(edgefix2->pos, edgefix3->pos);
402 d23 = d23vec.length();
404 edgefix2->fixed =
false;
407 edgefix1->fixed =
false;
416 edgept = edgept->next;
417 while (!edgept->fixed) {
418 if (edgept == startfix) {
421 edgept = edgept->next;
425 }
while ((edgefix != startfix) && (!stopped));
451 if (edgept->fixed && !edgept->next->fixed) {
455 edgept = edgept->
next;
456 }
while (edgept != startpt);
458 if (loopstart ==
nullptr && !startpt->fixed) {
460 startpt->
fixed =
true;
471 edgesum += edgept->runlength;
472 edgept = edgept->next;
473 }
while (!edgept->fixed && edgept != loopstart && edgesum < 126);
475 tprintf(
"Poly2:starting at (%d,%d)+%d=(%d,%d),%d to (%d,%d)\n",
476 linestart->pos.x, linestart->pos.y, linestart->dir,
477 linestart->vec.x, linestart->vec.y, edgesum, edgept->pos.x,
481 cutline(linestart, edgept, area);
483 while (edgept->next->fixed && edgept != loopstart) {
484 edgept = edgept->next;
488 while (edgept != loopstart);
494 edgept = edgept->next;
497 while (edgept != loopstart);
501 }
while (edgesum < 3);
505 edgept = edgept->next;
506 }
while (!edgept->fixed);
507 linestart->next = edgept;
508 edgept->prev = linestart;
509 linestart->vec.x = edgept->pos.x - linestart->pos.x;
510 linestart->vec.y = edgept->pos.y - linestart->pos.y;
511 }
while (edgept != loopstart);
531 EDGEPT *edgepts = stack_edgepts;
540 int32_t area = loop_box.
height();
541 if (!poly_wide_objects_better && loop_box.width() > area) {
542 area = loop_box.width();
545 edgesteps_to_edgepts(c_outline, edgepts);
547 EDGEPT *edgept = poly2(edgepts, area);
550 EDGEPT *prev_result =
nullptr;
552 auto *new_pt =
new EDGEPT;
553 new_pt->
pos = edgept->
pos;
554 new_pt->prev = prev_result;
555 if (prev_result ==
nullptr) {
558 prev_result->
next = new_pt;
559 new_pt->
prev = prev_result;
561 if (allow_detailed_fx) {
566 prev_result = new_pt;
567 edgept = edgept->
next;
568 }
while (edgept != startpt);
569 prev_result->
next = result;
570 result->
prev = prev_result;
571 if (edgepts != stack_edgepts) {
#define BOOL_VAR(name, val, comment)
TESSLINE * ApproximateOutline(bool allow_detailed_fx, C_OUTLINE *c_outline)
void tprintf(const char *format,...)
int cross(const TPOINT &other) const
static TESSLINE * BuildFromOutlineList(EDGEPT *outline)
int32_t pathlength() const
const TBOX & bounding_box() const
TDimension height() const