• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**********************************************************************
2  * File:        charcut.cpp  (Formerly charclip.c)
3  * Description: Code for character clipping
4  * Author:      Phil Cheatle
5  * Created:     Wed Nov 11 08:35:15 GMT 1992
6  *
7  * (C) Copyright 1992, Hewlett-Packard Ltd.
8  ** Licensed under the Apache License, Version 2.0 (the "License");
9  ** you may not use this file except in compliance with the License.
10  ** You may obtain a copy of the License at
11  ** http://www.apache.org/licenses/LICENSE-2.0
12  ** Unless required by applicable law or agreed to in writing, software
13  ** distributed under the License is distributed on an "AS IS" BASIS,
14  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  ** See the License for the specific language governing permissions and
16  ** limitations under the License.
17  *
18  **********************************************************************/
19 
20 #include "mfcpch.h"
21 #include          "charcut.h"
22 #include          "imgs.h"
23 #include          "svshowim.h"
24 //#include          "evnts.h"
25 #include          "notdll.h"
26 #include	  "scrollview.h"
27 
28 #define LARGEST(a,b) ( (a) > (b) ? (a) : (b) )
29 #define SMALLEST(a,b) ( (a) > (b) ? (b) : (a) )
30 #define BUG_OFFSET 1
31 #define EXTERN
32 
33 EXTERN INT_VAR (pix_word_margin, 3, "How far outside word BB to grow");
34 
35 extern IMAGE page_image;
36 
ELISTIZE(PIXROW)37 ELISTIZE (PIXROW)
38 /*************************************************************************
39  * PIXROW::PIXROW()
40  *
41  * Constructor for a specified size PIXROW from a blob
42  *************************************************************************/
43 PIXROW::PIXROW(inT16 pos, inT16 count, PBLOB *blob) {
44   OUTLINE_LIST *outline_list;
45   OUTLINE_IT outline_it;
46   POLYPT_LIST *pts_list;
47   POLYPT_IT pts_it;
48   inT16 i;
49   FCOORD pt;
50   FCOORD vec;
51   float y_coord;
52   inT16 x_coord;
53 
54   row_offset = pos;
55   row_count = count;
56   min = (inT16 *) alloc_mem (count * sizeof (inT16));
57   max = (inT16 *) alloc_mem (count * sizeof (inT16));
58   outline_list = blob->out_list ();
59   outline_it.set_to_list (outline_list);
60 
61   for (i = 0; i < count; i++) {
62     min[i] = MAX_INT16 - 1;
63     max[i] = -MAX_INT16 + 1;
64     y_coord = row_offset + i + 0.5;
65     for (outline_it.mark_cycle_pt ();
66     !outline_it.cycled_list (); outline_it.forward ()) {
67       pts_list = outline_it.data ()->polypts ();
68       pts_it.set_to_list (pts_list);
69       for (pts_it.mark_cycle_pt ();
70       !pts_it.cycled_list (); pts_it.forward ()) {
71         pt = pts_it.data ()->pos;
72         vec = pts_it.data ()->vec;
73         if ((vec.y () != 0) &&
74           (((pt.y () <= y_coord) && (pt.y () + vec.y () >= y_coord))
75           || ((pt.y () >= y_coord)
76         && (pt.y () + vec.y () <= y_coord)))) {
77           /* The segment crosses y_coord so find x-point and check for min/max. */
78           x_coord = (inT16) floor ((y_coord -
79             pt.y ()) * vec.x () / vec.y () +
80             pt.x () + 0.5);
81           if (x_coord < min[i])
82             min[i] = x_coord;
83           x_coord--;             //to get pix to left of line
84           if (x_coord > max[i])
85             max[i] = x_coord;
86         }
87       }
88     }
89   }
90 }
91 
92 
93 /*************************************************************************
94  * PIXROW::plot()
95  *
96  * Draw the PIXROW
97  *************************************************************************/
98 
99 #ifndef GRAPHICS_DISABLED
plot(ScrollView * fd) const100 void PIXROW::plot(ScrollView* fd  //where to paint
101                  ) const {
102   inT16 i;
103   inT16 y_coord;
104 
105   for (i = 0; i < row_count; i++) {
106     y_coord = row_offset + i;
107     if (min[i] <= max[i]) {
108       fd->Rectangle(min[i], y_coord, max[i] + 1, y_coord + 1);
109     }
110   }
111 }
112 #endif
113 
114 /*************************************************************************
115  * PIXROW::bounding_box()
116  *
117  * Generate bounding box for blob image
118  *************************************************************************/
119 
bad_box(int xsize,int ysize) const120 bool PIXROW::bad_box(  //return true if box exceeds image
121                      int xsize,
122                      int ysize) const {
123   TBOX bbox = bounding_box ();
124   if (bbox.left () < 0 || bbox.right () > xsize
125   || bbox.top () > ysize || bbox.bottom () < 0) {
126     tprintf("Box (%d,%d)->(%d,%d) bad compared to %d,%d\n",
127             bbox.left(),bbox.bottom(), bbox.right(), bbox.top(),
128             xsize, ysize);
129     return true;
130   }
131   return false;
132 }
133 
134 
135 /*************************************************************************
136  * PIXROW::bounding_box()
137  *
138  * Generate bounding box for blob image
139  *************************************************************************/
140 
bounding_box() const141 TBOX PIXROW::bounding_box() const {
142   inT16 i;
143   inT16 y_coord;
144   inT16 min_x = MAX_INT16 - 1;
145   inT16 min_y = MAX_INT16 - 1;
146   inT16 max_x = -MAX_INT16 + 1;
147   inT16 max_y = -MAX_INT16 + 1;
148 
149   for (i = 0; i < row_count; i++) {
150     y_coord = row_offset + i;
151     if (min[i] <= max[i]) {
152       if (y_coord < min_y)
153         min_y = y_coord;
154       if (y_coord + 1 > max_y)
155         max_y = y_coord + 1;
156       if (min[i] < min_x)
157         min_x = min[i];
158       if (max[i] + 1 > max_x)
159         max_x = max[i] + 1;
160     }
161   }
162   if (min_x > max_x || min_y > max_y)
163     return TBOX ();
164   else
165     return TBOX (ICOORD (min_x, min_y), ICOORD (max_x, max_y));
166 }
167 
168 
169 /*************************************************************************
170  * PIXROW::contract()
171  *
172  * Reduce the mins and maxs so that they end on black pixels
173  *************************************************************************/
174 
contract(IMAGELINE * imlines,inT16 x_offset,inT16 foreground_colour)175 void PIXROW::contract(                         //image array
176                       IMAGELINE *imlines,
177                       inT16 x_offset,          //of pixels[0]
178                       inT16 foreground_colour  //0 or 1
179                      ) {
180   inT16 i;
181   uinT8 *line_pixels;
182 
183   for (i = 0; i < row_count; i++) {
184     if (min[i] > max[i])
185       continue;
186 
187     line_pixels = imlines[i].pixels;
188     while (line_pixels[min[i] - x_offset] != foreground_colour) {
189       if (min[i] == max[i]) {
190         min[i] = MAX_INT16 - 1;
191         max[i] = -MAX_INT16 + 1;
192         goto nextline;
193       }
194       else
195         min[i]++;
196     }
197     while (line_pixels[max[i] - x_offset] != foreground_colour) {
198       if (min[i] == max[i]) {
199         min[i] = MAX_INT16 - 1;
200         max[i] = -MAX_INT16 + 1;
201         goto nextline;
202       }
203       else
204         max[i]--;
205     }
206     nextline:;
207     //goto label!
208   }
209 }
210 
211 
212 /*************************************************************************
213  * PIXROW::extend()
214  *
215  * 1 pixel extension in each direction to cover extra black area
216  *************************************************************************/
217 
extend(IMAGELINE * imlines,TBOX & imbox,PIXROW * prev,PIXROW * next,inT16 foreground_colour)218 BOOL8 PIXROW::extend(               //image array
219                      IMAGELINE *imlines,
220                      TBOX &imbox,
221                      PIXROW *prev,  //for prev blob
222                      PIXROW *next,  //for next blob
223                      inT16 foreground_colour) {
224   inT16 i;
225   inT16 x_offset = imbox.left ();
226   inT16 limit;
227   inT16 left_limit;
228   inT16 right_limit;
229   uinT8 *pixels = NULL;
230   uinT8 *pixels_below = NULL;    //row below current
231   uinT8 *pixels_above = NULL;    //row above current
232   BOOL8 changed = FALSE;
233 
234   pixels_above = imlines[0].pixels;
235   for (i = 0; i < row_count; i++) {
236     pixels_below = pixels;
237     pixels = pixels_above;
238     if (i < (row_count - 1))
239       pixels_above = imlines[i + 1].pixels;
240     else
241       pixels_above = NULL;
242 
243     /* Extend Left by one pixel*/
244     if (prev == NULL || prev->max[i] < prev->min[i])
245       limit = imbox.left ();
246     else
247       limit = prev->max[i] + 1;
248     if ((min[i] <= max[i]) &&
249       (min[i] > limit) &&
250     (pixels[min[i] - 1 - x_offset] == foreground_colour)) {
251       min[i]--;
252       changed = TRUE;
253     }
254 
255     /* Extend Right by one pixel*/
256     if (next == NULL || next->min[i] > next->max[i])
257       limit = imbox.right () - 1;//-1 to index inside pix
258     else
259       limit = next->min[i] - 1;
260     if ((min[i] <= max[i]) &&
261       (max[i] < limit) &&
262     (pixels[max[i] + 1 - x_offset] == foreground_colour)) {
263       max[i]++;
264       changed = TRUE;
265     }
266 
267     /* Extend down by one row */
268     if (pixels_below != NULL) {
269       if (min[i] < min[i - 1]) { //row goes left of row below
270         if (prev == NULL || prev->max[i - 1] < prev->min[i - 1])
271           left_limit = min[i];
272         else
273           left_limit = LARGEST (min[i], prev->max[i - 1] + 1);
274       }
275       else
276         left_limit = min[i - 1];
277 
278       if (max[i] > max[i - 1]) { //row goes right of row below
279         if (next == NULL || next->min[i - 1] > next->max[i - 1])
280           right_limit = max[i];
281         else
282           right_limit = SMALLEST (max[i], next->min[i - 1] - 1);
283       }
284       else
285         right_limit = max[i - 1];
286 
287       while ((left_limit <= right_limit) &&
288         (pixels_below[left_limit - x_offset] != foreground_colour))
289         left_limit++;            //find black extremity
290 
291       if ((left_limit <= right_limit) && (left_limit < min[i - 1])) {
292         min[i - 1] = left_limit; //widen left if poss
293         changed = TRUE;
294       }
295 
296       while ((left_limit <= right_limit) &&
297         (pixels_below[right_limit - x_offset] != foreground_colour))
298         right_limit--;           //find black extremity
299 
300       if ((left_limit <= right_limit) && (right_limit > max[i - 1])) {
301         max[i - 1] = right_limit;//widen right if poss
302         changed = TRUE;
303       }
304     }
305 
306     /* Extend up by one row */
307     if (pixels_above != NULL) {
308       if (min[i] < min[i + 1]) { //row goes left of row above
309         if (prev == NULL || prev->min[i + 1] > prev->max[i + 1])
310           left_limit = min[i];
311         else
312           left_limit = LARGEST (min[i], prev->max[i + 1] + 1);
313       }
314       else
315         left_limit = min[i + 1];
316 
317       if (max[i] > max[i + 1]) { //row goes right of row above
318         if (next == NULL || next->min[i + 1] > next->max[i + 1])
319           right_limit = max[i];
320         else
321           right_limit = SMALLEST (max[i], next->min[i + 1] - 1);
322       }
323       else
324         right_limit = max[i + 1];
325 
326       while ((left_limit <= right_limit) &&
327         (pixels_above[left_limit - x_offset] != foreground_colour))
328         left_limit++;            //find black extremity
329 
330       if ((left_limit <= right_limit) && (left_limit < min[i + 1])) {
331         min[i + 1] = left_limit; //widen left if poss
332         changed = TRUE;
333       }
334 
335       while ((left_limit <= right_limit) &&
336         (pixels_above[right_limit - x_offset] != foreground_colour))
337         right_limit--;           //find black extremity
338 
339       if ((left_limit <= right_limit) && (right_limit > max[i + 1])) {
340         max[i + 1] = right_limit;//widen right if poss
341         changed = TRUE;
342       }
343     }
344   }
345   return changed;
346 }
347 
348 
349 /*************************************************************************
350  * PIXROW::char_clip_image()
351  * Cut out a sub image for a character
352  *************************************************************************/
353 
char_clip_image(IMAGELINE * imlines,TBOX & im_box,ROW * row,IMAGE & clip_image,float & baseline_pos)354 void PIXROW::char_clip_image(                     //box of imlines extnt
355                              IMAGELINE *imlines,
356                              TBOX &im_box,
357                              ROW *row,            //row containing word
358                              IMAGE &clip_image,   //unscaled sq subimage
359                              float &baseline_pos  //baseline ht in image
360                             ) {
361   inT16 clip_image_xsize;        //sub image x size
362   inT16 clip_image_ysize;        //sub image y size
363   inT16 x_shift;                 //from pixrow to subim
364   inT16 y_shift;                 //from pixrow to subim
365   TBOX char_pix_box;              //bbox of char pixels
366   inT16 y_dest;
367   inT16 x_min;
368   inT16 x_max;
369   inT16 x_min_dest;
370   inT16 x_max_dest;
371   inT16 x_width;
372   inT16 y;
373 
374   clip_image_xsize = clip_image.get_xsize ();
375   clip_image_ysize = clip_image.get_ysize ();
376 
377   char_pix_box = bounding_box ();
378   /*
379     The y shift is calculated by first finding the coord of the bottom of the
380     image relative to the image lines. Then reducing this so by the amount
381     relative to the clip image size, necessary to vertically position the
382     character.
383   */
384   y_shift = char_pix_box.bottom () - row_offset -
385     (inT16) floor ((clip_image_ysize - char_pix_box.height () + 0.5) / 2);
386 
387   /*
388     The x_shift is the shift to be applied to the page coord in the pixrow to
389     generate a centred char in the clip image.  Thus the left hand edge of the
390     char is shifted to the margin width of the centred character.
391   */
392   x_shift = char_pix_box.left () -
393     (inT16) floor ((clip_image_xsize - char_pix_box.width () + 0.5) / 2);
394 
395   for (y = 0; y < row_count; y++) {
396     /*
397       Check that there is something in this row of the source that will fit in the
398       sub image.  If there is, reduce x range if necessary, then copy it
399     */
400     y_dest = y - y_shift;
401     if ((min[y] <= max[y]) && (y_dest >= 0) && (y_dest < clip_image_ysize)) {
402       x_min = min[y];
403       x_min_dest = x_min - x_shift;
404       if (x_min_dest < 0) {
405         x_min = x_min - x_min_dest;
406         x_min_dest = 0;
407       }
408       x_max = max[y];
409       x_max_dest = x_max - x_shift;
410       if (x_max_dest > clip_image_xsize - 1) {
411         x_max = x_max - (x_max_dest - (clip_image_xsize - 1));
412         x_max_dest = clip_image_xsize - 1;
413       }
414       x_width = x_max - x_min + 1;
415       if (x_width > 0) {
416         x_min -= im_box.left ();
417                                  //offset pixel ptr
418         imlines[y].pixels += x_min;
419         clip_image.put_line (x_min_dest, y_dest, x_width, imlines + y,
420           0);
421         imlines[y].init ();      //reset pixel ptr
422       }
423     }
424   }
425   /*
426     Baseline position relative to clip image: First find the baseline relative
427     to the page origin at the x coord of the centre of the character. Then
428     make this relative to the character bottom. Finally shift by the margin
429     between the bottom of the character and the bottom of the clip image.
430   */
431   if (row == NULL)
432     baseline_pos = 0;            //Not needed
433   else
434     baseline_pos = row->base_line ((char_pix_box.left () +
435       char_pix_box.right ()) / 2.0)
436       - char_pix_box.bottom ()
437       + ((clip_image_ysize - char_pix_box.height ()) / 2);
438 }
439 
440 
441 /*************************************************************************
442  * char_clip_word()
443  *
444  * Generate a PIXROW_LIST with one element for each blob in the word, together
445  * with the image lines for the whole word.
446  *************************************************************************/
447 
char_clip_word(WERD * word,IMAGE & bin_image,PIXROW_LIST * & pixrow_list,IMAGELINE * & imlines,TBOX & pix_box)448 void char_clip_word(                            //
449                     WERD *word,                 //word to be processed
450                     IMAGE &bin_image,           //whole image
451                     PIXROW_LIST *&pixrow_list,  //pixrows built
452                     IMAGELINE *&imlines,        //lines cut from image
453                     TBOX &pix_box                //box defining imlines
454                    ) {
455   TBOX word_box = word->bounding_box ();
456   PBLOB_LIST *blob_list;
457   PBLOB_IT blob_it;
458   PIXROW_IT pixrow_it;
459   inT16 pix_offset;              //Y pos of pixrow[0]
460   inT16 row_height;              //No of pix rows
461   inT16 imlines_x_offset;
462   PIXROW *prev;
463   PIXROW *next;
464   PIXROW *current;
465   BOOL8 changed;                 //still improving
466   BOOL8 just_changed;            //still improving
467   inT16 iteration_count = 0;
468   inT16 foreground_colour;
469 
470   if (word->flag (W_INVERSE))
471     foreground_colour = 1;
472   else
473     foreground_colour = 0;
474 
475   /* Define region for max pixrow expansion */
476   pix_box = word_box;
477   pix_box.move_bottom_edge (-pix_word_margin);
478   pix_box.move_top_edge (pix_word_margin);
479   pix_box.move_left_edge (-pix_word_margin);
480   pix_box.move_right_edge (pix_word_margin);
481   pix_box -= TBOX (ICOORD (0, 0 + BUG_OFFSET),
482     ICOORD (bin_image.get_xsize (),
483     bin_image.get_ysize () - BUG_OFFSET));
484 
485   /* Generate pixrows list */
486 
487   pix_offset = pix_box.bottom ();
488   row_height = pix_box.height ();
489   blob_list = word->blob_list ();
490   blob_it.set_to_list (blob_list);
491 
492   pixrow_list = new PIXROW_LIST;
493   pixrow_it.set_to_list (pixrow_list);
494 
495   for (blob_it.mark_cycle_pt (); !blob_it.cycled_list (); blob_it.forward ()) {
496     PIXROW *row = new PIXROW (pix_offset, row_height, blob_it.data ());
497     ASSERT_HOST (!row->
498       bad_box (bin_image.get_xsize (), bin_image.get_ysize ()));
499     pixrow_it.add_after_then_move (row);
500   }
501 
502   imlines = generate_imlines (bin_image, pix_box);
503 
504   /* Contract pixrows - shrink min and max back to black pixels */
505 
506   imlines_x_offset = pix_box.left ();
507 
508   pixrow_it.move_to_first ();
509   for (pixrow_it.mark_cycle_pt ();
510   !pixrow_it.cycled_list (); pixrow_it.forward ()) {
511     ASSERT_HOST (!pixrow_it.data ()->
512       bad_box (bin_image.get_xsize (), bin_image.get_ysize ()));
513     pixrow_it.data ()->contract (imlines, imlines_x_offset,
514       foreground_colour);
515     ASSERT_HOST (!pixrow_it.data ()->
516       bad_box (bin_image.get_xsize (), bin_image.get_ysize ()));
517   }
518 
519   /* Expand pixrows iteratively 1 pixel at a time */
520   do {
521     changed = FALSE;
522     pixrow_it.move_to_first ();
523     prev = NULL;
524     current = NULL;
525     next = pixrow_it.data ();
526     for (pixrow_it.mark_cycle_pt ();
527     !pixrow_it.cycled_list (); pixrow_it.forward ()) {
528       prev = current;
529       current = next;
530       if (pixrow_it.at_last ())
531         next = NULL;
532       else
533         next = pixrow_it.data_relative (1);
534       just_changed = current->extend (imlines, pix_box, prev, next,
535         foreground_colour);
536       ASSERT_HOST (!current->
537         bad_box (bin_image.get_xsize (),
538         bin_image.get_ysize ()));
539       changed = changed || just_changed;
540     }
541     iteration_count++;
542   }
543   while (changed);
544 }
545 
546 
547 /*************************************************************************
548  * generate_imlines()
549  * Get an array of IMAGELINES  holding a portion of an image
550  *************************************************************************/
551 
generate_imlines(IMAGE & bin_image,TBOX & pix_box)552 IMAGELINE *generate_imlines(                   //get some imagelines
553                             IMAGE &bin_image,  //from here
554                             TBOX &pix_box) {
555   IMAGELINE *imlines;            //array of lines
556   int i;
557 
558   imlines = new IMAGELINE[pix_box.height ()];
559   for (i = 0; i < pix_box.height (); i++) {
560     imlines[i].init (pix_box.width ());
561                                  //coord to start at
562     bin_image.fast_get_line (pix_box.left (),
563       pix_box.bottom () + i + BUG_OFFSET,
564     //line to get
565       pix_box.width (),          //width to get
566       imlines + i);              //dest imline
567   }
568   return imlines;
569 }
570 
571 
572 /*************************************************************************
573  * display_clip_image()
574  * All the boring user interface bits to let you see what's going on
575  *************************************************************************/
576 
577 #ifndef GRAPHICS_DISABLED
display_clip_image(WERD * word,IMAGE & bin_image,PIXROW_LIST * pixrow_list,TBOX & pix_box)578 ScrollView* display_clip_image(WERD *word,                //word to be processed
579                           IMAGE &bin_image,          //whole image
580                           PIXROW_LIST *pixrow_list,  //pixrows built
581                           TBOX &pix_box               //box of subimage
582                          ) {
583   ScrollView* clip_window;            //window for debug
584   TBOX word_box = word->bounding_box ();
585   int border = word_box.height () / 2;
586   TBOX display_box = word_box;
587 
588   display_box.move_bottom_edge (-border);
589   display_box.move_top_edge (border);
590   display_box.move_left_edge (-border);
591   display_box.move_right_edge (border);
592   display_box -= TBOX (ICOORD (0, 0 - BUG_OFFSET),
593     ICOORD (bin_image.get_xsize (),
594     bin_image.get_ysize () - BUG_OFFSET));
595 
596   pgeditor_msg ("Creating Clip window...");
597   clip_window = new ScrollView("Clipped Blobs",
598     editor_word_xpos, editor_word_ypos,
599     3 * (word_box.width () + 2 * border),
600     3 * (word_box.height () + 2 * border),
601     display_box.left () + display_box.right (),
602     display_box.bottom () - BUG_OFFSET +
603     display_box.top () - BUG_OFFSET,
604     true);
605   // ymin, ymax
606   pgeditor_msg ("Creating Clip window...Done");
607 
608   clip_window->Clear();
609   sv_show_sub_image (&bin_image,
610     display_box.left (),
611     display_box.bottom (),
612     display_box.width (),
613     display_box.height (),
614     clip_window,
615     display_box.left (), display_box.bottom () - BUG_OFFSET);
616 
617   word->plot (clip_window, ScrollView::RED);
618   word_box.plot (clip_window, ScrollView::BLUE, ScrollView::BLUE);
619   pix_box.plot (clip_window, ScrollView::BLUE, ScrollView::BLUE);
620   plot_pixrows(pixrow_list, clip_window);
621   return clip_window;
622 }
623 
624 
625 /*************************************************************************
626  * display_images()
627  * Show a pair of clip and scaled character images and wait for key before
628  * continuing.
629  *************************************************************************/
630 
display_images(IMAGE & clip_image,IMAGE & scaled_image)631 void display_images(IMAGE &clip_image, IMAGE &scaled_image) {
632   ScrollView* clip_im_window;         //window for debug
633   ScrollView* scale_im_window;        //window for debug
634   inT16 i;
635 
636                                  // xmin xmax ymin ymax
637   clip_im_window = new ScrollView ("Clipped Blob", editor_word_xpos - 20,
638       editor_word_ypos - 100, 5 * clip_image.get_xsize (),
639       5 * clip_image.get_ysize (), clip_image.get_xsize (),
640       clip_image.get_ysize (), true);
641 
642   sv_show_sub_image (&clip_image,
643     0, 0,
644     clip_image.get_xsize (), clip_image.get_ysize (),
645     clip_im_window, 0, 0);
646 
647   clip_im_window->Pen(255,0,0);
648   for (i = 1; i < clip_image.get_xsize (); i++) {
649     clip_im_window->SetCursor(i,0);
650     clip_im_window->DrawTo(i, clip_image.get_xsize ());
651   }
652   for (i = 1; i < clip_image.get_ysize (); i++) {
653     clip_im_window->SetCursor(0,i);
654     clip_im_window->DrawTo(clip_image.get_xsize (),i);
655 
656   }
657 
658                                  // xmin xmax ymin ymax
659   scale_im_window = new ScrollView ("Scaled Blob", editor_word_xpos + 300,
660       editor_word_ypos - 100, 5 * scaled_image.get_xsize (),
661       5 * scaled_image.get_ysize (), scaled_image.get_xsize (),
662       scaled_image.get_ysize (), true);
663 
664   sv_show_sub_image (&scaled_image,
665     0, 0,
666     scaled_image.get_xsize (), scaled_image.get_ysize (),
667     scale_im_window, 0, 0);
668 
669   scale_im_window->Pen(255,0,0);
670   for (i = 1; i < scaled_image.get_xsize (); i++) {
671     scale_im_window->SetCursor(i,0);
672     scale_im_window->DrawTo(i, scaled_image.get_xsize ());
673   }
674   for (i = 1; i < scaled_image.get_ysize (); i++) {
675     scale_im_window->SetCursor(0,i);
676     scale_im_window->DrawTo(scaled_image.get_xsize (),i);
677   }
678 
679   ScrollView::Update();
680 }
681 
682 
683 /*************************************************************************
684  * plot_pixrows()
685  * Display a list of pixrows
686  *************************************************************************/
687 
plot_pixrows(PIXROW_LIST * pixrow_list,ScrollView * win)688 void plot_pixrows(  //plot for all blobs
689                   PIXROW_LIST *pixrow_list,
690                   ScrollView* win) {
691   PIXROW_IT pixrow_it(pixrow_list);
692   inT16 colour = ScrollView::RED;
693 
694   for (pixrow_it.mark_cycle_pt ();
695   !pixrow_it.cycled_list (); pixrow_it.forward ()) {
696     if (colour > ScrollView::RED + 7)
697       colour = ScrollView::RED;
698 
699    win->Pen((ScrollView::Color) colour);
700     pixrow_it.data ()->plot (win);
701     colour++;
702   }
703 }
704 #endif
705