21 #include "allheaders.h" 38 static void position_outline(
40 C_OUTLINE_LIST *destlist
43 C_OUTLINE_IT it = destlist;
45 C_OUTLINE_IT child_it = outline->
child ();
49 dest_outline = it.data ();
51 if (*dest_outline < *outline) {
53 dest_outline = it.extract ();
55 it.add_after_then_move (outline);
57 child_it.add_to_end (dest_outline);
58 while (!it.at_last ()) {
61 dest_outline = it.data ();
62 if (*dest_outline < *outline) {
64 dest_outline = it.extract ();
65 child_it.add_to_end (dest_outline);
74 else if (*outline < *dest_outline) {
75 position_outline (outline, dest_outline->
child ());
81 while (!it.at_first ());
83 it.add_to_end (outline);
94 #ifndef GRAPHICS_DISABLED 95 static void plot_outline_list(
102 C_OUTLINE_IT it = list;
104 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
105 outline = it.data ();
107 outline->
plot (window, colour);
108 if (!outline->
child ()->empty ())
109 plot_outline_list (outline->
child (), window,
110 child_colour, child_colour);
116 static void plot_normed_outline_list(
const DENORM& denorm,
117 C_OUTLINE_LIST *list,
121 C_OUTLINE_IT it(list);
122 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
125 if (!outline->
child()->empty())
126 plot_normed_outline_list(denorm, outline->
child(), child_colour,
127 child_colour, window);
139 static void reverse_outline_list(C_OUTLINE_LIST *list) {
140 C_OUTLINE_IT it = list;
142 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
146 if (!outline->
child()->empty())
147 reverse_outline_list(outline->
child());
161 for (C_OUTLINE_IT ol_it(outline_list); !ol_it.empty(); ol_it.forward()) {
164 position_outline(outline, &outlines);
172 C_OUTLINE_IT it(&outlines);
173 it.add_to_end(outline);
187 C_OUTLINE_LIST* outline_list,
188 C_BLOB_IT* good_blobs_it,
189 C_BLOB_IT* bad_blobs_it) {
191 C_OUTLINE_LIST nested_outlines;
192 for (C_OUTLINE_IT ol_it(outline_list); !ol_it.empty(); ol_it.forward()) {
195 position_outline(outline, &nested_outlines);
198 for (C_OUTLINE_IT ol_it(&nested_outlines); !ol_it.empty(); ol_it.forward()) {
200 bool blob_is_good = good_blob;
204 blob_is_good =
false;
205 ol_it.add_list_after(outline->
child());
211 if (!blob_is_good && bad_blobs_it != NULL)
212 bad_blobs_it->add_after_then_move(blob);
214 good_blobs_it->add_after_then_move(blob);
222 C_OUTLINE_IT ol_it(&outlines);
223 for (ol_it.mark_cycle_pt(); !ol_it.cycled_list(); ol_it.forward()) {
227 reverse_outline_list(outline->
child());
239 C_OUTLINE_LIST outlines;
241 return new C_BLOB(&outlines);
253 C_OUTLINE_IT it =
const_cast<C_OUTLINE_LIST*
>(&outlines);
256 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
257 outline = it.data ();
272 C_OUTLINE_IT it = &outlines;
276 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
277 outline = it.data ();
278 total += outline->
area ();
291 C_OUTLINE_IT it = &outlines;
295 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
311 C_OUTLINE_IT it = &outlines;
315 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
316 outline = it.data ();
334 C_OUTLINE_IT it = &outlines;
338 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
339 outline = it.data ();
355 C_OUTLINE_IT it(&outlines);
357 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
358 it.data ()->move (vec);
363 C_OUTLINE_LIST new_outlines;
364 C_OUTLINE_IT src_it(outlines);
365 C_OUTLINE_IT dest_it(&new_outlines);
366 while (!src_it.empty()) {
367 C_OUTLINE* old_outline = src_it.extract();
370 if (!old_outline->
child()->empty()) {
372 C_OUTLINE_IT child_it(new_outline->
child());
373 child_it.add_list_after(old_outline->
child());
376 dest_it.add_to_end(new_outline);
378 src_it.add_list_after(&new_outlines);
393 static void ComputeEdgeOffsetsOutlineList(
int threshold, Pix* pix,
394 C_OUTLINE_LIST *list) {
395 C_OUTLINE_IT it(list);
396 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
398 if (pix != NULL && pixGetDepth(pix) == 8)
402 if (!outline->
child()->empty())
403 ComputeEdgeOffsetsOutlineList(threshold, pix, outline->
child());
410 ComputeEdgeOffsetsOutlineList(threshold, pix, &outlines);
429 int left = box.
left();
430 int width = box.
width();
431 int bottom = box.
bottom();
437 C_OUTLINE_IT it(&outlines);
438 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
441 for (
int s = 0; s < outline->
pathlength(); ++s) {
442 if (pos.
y() < y_mins[pos.
x() - left])
443 y_mins[pos.
x() - left] = pos.
y();
444 pos += outline->
step(s);
448 int bottom_extent = 0;
449 for (
int x = 0; x <= width; ++x) {
450 if (y_mins[x] == bottom || y_mins[x] == bottom + 1)
454 int best_min = box.
top();
456 int prev_y = box.
top();
457 int prev_prev_y = box.
top();
458 for (
int x = 0; x < width; x += prev_run) {
460 int y_at_x = y_mins[x];
462 while (x + run <= width && y_mins[x + run] == y_at_x) ++run;
463 if (y_at_x > bottom + 1) {
467 while (x + total_run <= width &&
468 (y_mins[x + total_run] == y_at_x ||
469 y_mins[x + total_run] == y_at_x + 1)) ++total_run;
471 if (prev_prev_y > y_at_x + 1 || x + total_run > width ||
472 y_mins[x + total_run] > y_at_x + 1) {
475 if (prev_run > 0 && prev_y == y_at_x + 1) total_run += prev_run;
476 if (total_run > bottom_extent && y_at_x < best_min) {
482 prev_prev_y = prev_y;
485 return best_min == box.
top() ? bottom : best_min;
488 static void render_outline_list(C_OUTLINE_LIST *list,
489 int left,
int top, Pix* pix) {
490 C_OUTLINE_IT it(list);
491 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
493 outline->
render(left, top, pix);
494 if (!outline->
child()->empty())
495 render_outline_list(outline->
child(), left, top, pix);
499 static void render_outline_list_outline(C_OUTLINE_LIST *list,
500 int left,
int top, Pix* pix) {
501 C_OUTLINE_IT it(list);
502 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
511 Pix* pix = pixCreate(box.
width(), box.
height(), 1);
512 render_outline_list(&outlines, box.
left(), box.
top(), pix);
520 Pix* pix = pixCreate(box.
width(), box.
height(), 1);
521 render_outline_list_outline(&outlines, box.
left(), box.
top(), pix);
531 #ifndef GRAPHICS_DISABLED 535 plot_outline_list(&outlines, window, blob_colour, child_colour);
544 plot_normed_outline_list(denorm, &outlines, blob_colour, child_colour,
#define ELISTIZE(CLASSNAME)
inT32 count_transitions(inT32 threshold)
void render_outline(int left, int top, Pix *pix) const
void rotate(const FCOORD &rotation)
inT16 turn_direction() const
void plot(ScrollView *window, ScrollView::Color blob_colour, ScrollView::Color child_colour)
void render(int left, int top, Pix *pix) const
inT32 count_transitions(inT32 threshold)
TBOX bounding_box() const
ICOORD step(int index) const
void ComputeEdgeOffsets(int threshold, Pix *pix)
inT16 EstimateBaselinePosition()
void move(const ICOORD vec)
void RotateOutlineList(const FCOORD &rotation, C_OUTLINE_LIST *outlines)
inT16 x() const
access function
void ComputeEdgeOffsets(int threshold, Pix *pix)
bool IsLegallyNested() const
const TBOX & bounding_box() const
void plot(ScrollView *window, ScrollView::Color colour) const
void set_flag(C_OUTLINE_FLAGS mask, BOOL8 value)
void CheckInverseFlagAndDirection()
const ICOORD & start_pos() const
static C_BLOB * FakeBlob(const TBOX &box)
void plot_normed(const DENORM &denorm, ScrollView::Color colour, ScrollView *window) const
static void FakeOutline(const TBOX &box, C_OUTLINE_LIST *outlines)
void plot_normed(const DENORM &denorm, ScrollView::Color blob_colour, ScrollView::Color child_colour, ScrollView *window)
const double kMaxPerimeterWidthRatio
static void ConstructBlobsFromOutlines(bool good_blob, C_OUTLINE_LIST *outline_list, C_BLOB_IT *good_blobs_it, C_BLOB_IT *bad_blobs_it)
void init_to_size(int size, T t)
void ComputeBinaryOffsets()
inT16 y() const
access_function