示例#1
0
void
main (int argc, string argv[])
{
  int code;
  string font_name = read_command_line (argc, argv);
  bitmap_font_type f = get_bitmap_font (font_name, atou (dpi));
  string font_basename = basename (font_name);

  /* Initializing the display might involve forking a process.  We
     wouldn't want that process to get copies of open output files,
     since then when it exited, random stuff might get written to the
     end of the file.  */
  init_display (f);

  if (logging)
    log_file = xfopen (concat (font_basename, ".log"), "w");

  if (strlen (BITMAP_FONT_COMMENT (f)) > 0)
    REPORT1 ("{%s}\n", BITMAP_FONT_COMMENT (f));

  if (output_name == NULL)
    output_name = font_basename;

  bzr_start_output (output_name, f);

  /* The main loop: for each character, find the outline of the shape,
     then fit the splines to it.  */
  for (code = starting_char; code <= ending_char; code++)
    {
      pixel_outline_list_type pixels;
      spline_list_array_type splines;
      char_info_type *c = get_char (font_name, code);
    
      if (c == NULL) continue;

      REPORT1 ("[%u ", code);
      if (logging)
	{
	  LOG ("\n\n\f");
	  print_char (log_file, *c);
	}

      x_start_char (*c);
      pixels = find_outline_pixels (*c);
      /* `find_outline_pixels' uses corners as the coordinates, instead
         of the pixel centers.  So we have to increase the bounding box.  */
      CHAR_MIN_COL (*c)--; CHAR_MAX_COL (*c)++;
      CHAR_MIN_ROW (*c)--; CHAR_MAX_ROW (*c)++;

      REPORT ("|");
      splines = fitted_splines (pixels);

      bzr_output_char (*c, splines);
      
      /* Flush output before displaying the character, in case the user
         is interested in looking at it and the online version
         simultaneously.  */
      flush_log_output ();

      x_output_char (*c, splines);
      REPORT ("]\n");

      /* If the character was empty, it won't have a bitmap.  */
      if (BITMAP_BITS (CHAR_BITMAP (*c)) != NULL)
        free_bitmap (&CHAR_BITMAP (*c));

      free_pixel_outline_list (&pixels);
      free_spline_list_array (&splines);
    }

  bzr_finish_output ();
  close_display ();

  close_font (font_name);

  exit (0);
}
示例#2
0
/* at_splines_new_full modifies its 'bitmap' argument
   when it does the thin_image thing.
*/
at_spline_list_array_type * 
at_splines_new_full(at_bitmap_type *       const bitmap,
                    at_fitting_opts_type * const opts,
                    at_msg_func                  msg_func, 
                    void *                 const msg_data,
                    at_progress_func             notify_progress,
                    void *                 const progress_data,
                    at_testcancel_func           test_cancel,
                    void *                 const testcancel_data) {

    at_spline_list_array_type * retval;
    image_header_type image_header;
    pixel_outline_list_type pixelOutlineList;
    at_exception_type exp;
    distance_map_type distanceMap;
    bool haveDistMap;

    exp = at_exception_new(msg_func, msg_data);

    image_header.width  = at_bitmap_get_width(bitmap);
    image_header.height = at_bitmap_get_height(bitmap);

    if (opts->centerline) {
        if (opts->preserve_width) {
            /* Preserve line width prior to thinning. */
            bool const paddedTrue = true;
            distanceMap = new_distance_map(*bitmap, 255, paddedTrue, &exp);
            haveDistMap = true;
        } else
            haveDistMap = false;
        thin_image(bitmap, opts->backgroundSpec, opts->background_color, &exp);
    } else
        haveDistMap = false;

    if (at_exception_got_fatal(&exp))
        retval = NULL;
    else {
        if (opts->centerline) {
            pixel background_color;

            if (opts->backgroundSpec) 
                background_color = opts->background_color;
            else
                PPM_ASSIGN(background_color, 255, 255, 255);
            
            pixelOutlineList =
                find_centerline_pixels(*bitmap, background_color, 
                                       notify_progress, progress_data,
                                       test_cancel, testcancel_data, &exp);
        } else
            pixelOutlineList =
                find_outline_pixels(*bitmap,
                                    opts->backgroundSpec,
                                    opts->background_color, 
                                    notify_progress, progress_data,
                                    test_cancel, testcancel_data, &exp);

        if (at_exception_got_fatal(&exp) ||
            (test_cancel && test_cancel(testcancel_data)))
            retval = NULL;
        else {
            at_spline_list_array_type * splinesP;
        
            MALLOCVAR_NOFAIL(splinesP); 
            fit_outlines_to_splines(pixelOutlineList, opts,
                                    haveDistMap ? &distanceMap : NULL,
                                    image_header.width,
                                    image_header.height,
                                    &exp,
                                    notify_progress, progress_data,
                                    test_cancel, testcancel_data,
                                    splinesP);

            if (at_exception_got_fatal(&exp) ||
                (test_cancel && test_cancel(testcancel_data)))
                retval = NULL;
            else {
                if (notify_progress)
                    notify_progress(1.0, progress_data);

                retval = splinesP;
            }
            free_pixel_outline_list(&pixelOutlineList);
        }
        if (haveDistMap)
            free_distance_map(&distanceMap);
    }
    return retval;
}
示例#3
0
/* at_splines_new_full modify its argument: BITMAP
   when despeckle, quantize and/or thin_image are invoked. */
at_splines_type *
at_splines_new_full (at_bitmap * bitmap,
                     at_fitting_opts_type * opts,
                     at_msg_func msg_func,
                     gpointer msg_data,
                     at_progress_func notify_progress,
                     gpointer progress_data,
                     at_testcancel_func test_cancel,
                     gpointer testcancel_data)
{
    image_header_type image_header;
    at_splines_type * splines = NULL;
    pixel_outline_list_type pixels;
    QuantizeObj *myQuant = NULL; /* curently not used */
    at_exception_type exp     = at_exception_new(msg_func, msg_data);
    at_distance_map dist_map, *dist = NULL;

#define CANCELP (test_cancel && test_cancel(testcancel_data))
#define FATALP  (at_exception_got_fatal(&exp))
#define FREE_SPLINE() do {if (splines) {at_splines_free(splines); splines = NULL;}} while(0)

#define CANCEL_THEN_CLEANUP_DIST() if (CANCELP) goto cleanup_dist;
#define CANCEL_THEN_CLEANUP_PIXELS() if (CANCELP) {FREE_SPLINE(); goto cleanup_pixels;}

#define FATAL_THEN_RETURN() if (FATALP) return splines;
#define FATAL_THEN_CLEANUP_DIST() if (FATALP) goto cleanup_dist;
#define FATAL_THEN_CLEANUP_PIXELS() if (FATALP) {FREE_SPLINE(); goto cleanup_pixels;}

    if (opts->despeckle_level > 0)
    {
        despeckle (bitmap,
                   opts->despeckle_level,
                   opts->despeckle_tightness,
                   opts->noise_removal,
                   &exp);
        FATAL_THEN_RETURN();
    }

    image_header.width = at_bitmap_get_width(bitmap);
    image_header.height = at_bitmap_get_height(bitmap);

    if (opts->color_count > 0)
    {
        quantize (bitmap, opts->color_count, opts->background_color, &myQuant, &exp);
        if (myQuant)
            quantize_object_free(myQuant); /* curently not used */
        FATAL_THEN_RETURN();
    }

    if (opts->centerline)
    {
        if (opts->preserve_width)
        {
            /* Preserve line width prior to thinning. */
            dist_map = new_distance_map(bitmap, 255, /*padded=*/TRUE, &exp);
            dist = &dist_map;
            FATAL_THEN_RETURN();
        }
        /* Hereafter, dist is allocated. dist must be freed if
        the execution is canceled or exception is raised;
         use FATAL_THEN_CLEANUP_DIST. */
        thin_image (bitmap, opts->background_color, &exp);
        FATAL_THEN_CLEANUP_DIST()
    }

    /* Hereafter, pixels is allocated. pixels must be freed if
       the execution is canceled; use CANCEL_THEN_CLEANUP_PIXELS. */
    if (opts->centerline)
    {
        at_color background_color = { 0xff, 0xff, 0xff };
        if (opts->background_color)
            background_color = *opts->background_color;

        pixels = find_centerline_pixels(bitmap, background_color,
                                        notify_progress, progress_data,
                                        test_cancel, testcancel_data, &exp);
    }
    else
        pixels = find_outline_pixels(bitmap, opts->background_color,
                                     notify_progress, progress_data,
                                     test_cancel, testcancel_data, &exp);
    FATAL_THEN_CLEANUP_DIST();
    CANCEL_THEN_CLEANUP_DIST();

    XMALLOC(splines, sizeof(at_splines_type));
    *splines = fitted_splines (pixels, opts, dist,
                               image_header.width,
                               image_header.height,
                               &exp,
                               notify_progress, progress_data,
                               test_cancel, testcancel_data);
    FATAL_THEN_CLEANUP_PIXELS();
    CANCEL_THEN_CLEANUP_PIXELS();

    if (notify_progress)
        notify_progress(1.0, progress_data);

cleanup_pixels:
    free_pixel_outline_list (&pixels);
cleanup_dist:
    if (dist)
        free_distance_map (dist);
    return splines;
#undef CANCELP
#undef FATALP
#undef FREE_SPLINE
#undef CANCEL_THEN_CLEANUP_DIST
#undef CANCEL_THEN_CLEANUP_PIXELS

#undef FATAL_THEN_RETURN
#undef FATAL_THEN_CLEANUP_DIST
#undef FATAL_THEN_CLEANUP_PIXELS

}