Skip to content
imlib.c 36.2 KiB
Newer Older
   if (wrap_width)
   {
      gib_imlib_get_text_size(fn, "M M", style, &t_width, NULL,
                              IMLIB_TEXT_TO_RIGHT);
      gib_imlib_get_text_size(fn, "M", style, &m_width, NULL,
                              IMLIB_TEXT_TO_RIGHT);
      space_width = t_width - (2 * m_width);
      w = wrap_width;
      l = lines;
      while (l)
      {
         line_width = 0;
         p = (char *) l->data;
         /* quick check to see if whole line fits okay */
         gib_imlib_get_text_size(fn, p, style, &tw, &th, IMLIB_TEXT_TO_RIGHT);
         if (tw <= w) {
            list = gib_list_add_end(list, estrdup(p));
         } else if (strlen(p) == 0) {
            list = gib_list_add_end(list, estrdup(""));
         } else if (!strcmp(p, " ")) {
            list = gib_list_add_end(list, estrdup(" "));
         } else {
            words = gib_string_split(p, " ");
            if (words) {
               ll = words;
               while (ll) {
                  pp = (char *) ll->data;
                  if (strcmp(pp, " ")) {
                     gib_imlib_get_text_size(fn, pp, style, &tw, &th,
                                             IMLIB_TEXT_TO_RIGHT);
                     if (line_width == 0)
                        new_width = tw;
                     else
                        new_width = line_width + space_width + tw;
                     if (new_width <= w) {
                        /* add word to line */
                        if (line) {
                           int len;

                           len = strlen(line) + strlen(pp) + 2;
                           temp = emalloc(len);
                           snprintf(temp, len, "%s %s", line, pp);
                           free(line);
                           line = temp;
                        } else {
                          line = estrdup(pp);
                        }
                        line_width = new_width;
                     } else if (line_width == 0) {
                        /* can't fit single word in :/
                           increase width limit to width of word
                           and jam the bastard in anyhow */
                        w = tw;
                        line = estrdup(pp);
                        line_width = new_width;
                     } else {
                        /* finish this line, start next and add word there */
                        if (line) {
                           list = gib_list_add_end(list, estrdup(line));
                           free(line);
                           line = NULL;
                        }
                        line = estrdup(pp);
                        line_width = tw;
                     }
                  }
                  ll = ll->next;
               }
               if (line) {
                  /* finish last line */
                  list = gib_list_add_end(list, estrdup(line));
                  free(line);
                  line = NULL;
                  line_width = 0;
               }
               gib_list_free_and_data(words);
            }
         }
         l = l->next;
      }
      gib_list_free_and_data(lines);
      lines = list;
   }
   return lines;
}

void feh_edit_inplace_lossless_rotate(winwidget w, int orientation) {
  FILE *input_file;
  FILE *output_file;
  struct jpeg_decompress_struct srcinfo;
  struct jpeg_compress_struct dstinfo;
  struct jpeg_error_mgr jsrcerr, jdsterr;
  jvirt_barray_ptr * src_coef_arrays;
  jvirt_barray_ptr * dst_coef_arrays;
  JCOPY_OPTION copyoption;
  jpeg_transform_info transformoption;
  int len;
  char *outfilename;
  char *infilename = FEH_FILE(w->file->data)->filename;

  copyoption = JCOPYOPT_ALL;
  transformoption.transform = JXFORM_NONE;
  transformoption.trim = FALSE;
  transformoption.force_grayscale = FALSE;

  if (orientation == 1) {
    transformoption.transform = JXFORM_ROT_90;
  } else if (orientation == 2) {
    transformoption.transform = JXFORM_ROT_180;
  } else {
    transformoption.transform = JXFORM_ROT_270;
  }
  
  if ((input_file = fopen(infilename, "rb")) == NULL) {
    weprintf("couldn't open file for reading: %s\n", infilename);
    D_RETURN_(4);
  }
  len = strlen(infilename) + sizeof(".tmp") + 1;
  outfilename = emalloc(len);
  snprintf(outfilename, len, "%s.tmp", infilename);

  if ((output_file = fopen(outfilename, "wb")) == NULL) {
    weprintf("couldn't open file for writing: %s\n", outfilename);
    free(outfilename);
    fclose(input_file);
    D_RETURN_(4);
  }

  /* Initialize the JPEG decompression object with default error handling. */
  srcinfo.err = jpeg_std_error(&jsrcerr);
  jpeg_create_decompress(&srcinfo);

  /* Initialize the JPEG compression object with default error handling. */
  dstinfo.err = jpeg_std_error(&jdsterr);
  jpeg_create_compress(&dstinfo);
  jsrcerr.trace_level = jdsterr.trace_level;

  /* Specify data source for decompression */
  jpeg_stdio_src(&srcinfo, input_file);

  /* Enable saving of extra markers that we want to copy */
  jcopy_markers_setup(&srcinfo, copyoption);

  /* Read file header */
  (void) jpeg_read_header(&srcinfo, TRUE);

  /* Any space needed by a transform option must be requested before
   * jpeg_read_coefficients so that memory allocation will be done right.
   */
  jtransform_request_workspace(&srcinfo, &transformoption);

  /* Read source file as DCT coefficients */
  src_coef_arrays = jpeg_read_coefficients(&srcinfo);

  /* Initialize destination compression parameters from source values */
  jpeg_copy_critical_parameters(&srcinfo, &dstinfo);

  /* Adjust destination parameters if required by transform options;
   * also find out which set of coefficient arrays will hold the output.
   */
  dst_coef_arrays = jtransform_adjust_parameters(&srcinfo, &dstinfo,
             src_coef_arrays,
             &transformoption);

  /* Specify data destination for compression */
  jpeg_stdio_dest(&dstinfo, output_file);

  /* Start compressor (note no image data is actually written here) */
  jpeg_write_coefficients(&dstinfo, dst_coef_arrays);

  /* Copy to the output file any extra markers that we want to preserve */
  jcopy_markers_execute(&srcinfo, &dstinfo, copyoption);

  /* Execute image transformation */
  jtransform_execute_transformation(&srcinfo, &dstinfo,
            src_coef_arrays,
            &transformoption);

  /* Finish compression and release memory */
  jpeg_finish_compress(&dstinfo);
  jpeg_destroy_compress(&dstinfo);

  (void) jpeg_finish_decompress(&srcinfo);
  jpeg_destroy_decompress(&srcinfo);

  fclose(input_file);
  fclose(output_file);

  /* TODO fix EXIF tags (orientation, width, height) */

  /* rename outfilename to infilename.. if it worked */
  if (jsrcerr.num_warnings > 0) {
    weprintf("got errors from libjpeg (%d), not replacing file\n", jsrcerr.num_warnings);
  } else {
    if (rename(outfilename, infilename)) {
      weprintf("failed to replace file %s with %s\n", infilename, outfilename);
    }
  }
  free(outfilename);
}

void
feh_draw_actions(winwidget w)
{
   static Imlib_Font fn = NULL;
   int tw = 0, th = 0;
   int max_tw = 0;
   int line_th = 0;
   Imlib_Image im = NULL;
   static DATA8 atab[256];
   int i = 0;
   int num_actions = 0;
   
   D_ENTER(4);

// count the number of defined actions
   for (num_actions=0;opt.actions[num_actions];num_actions++)
   	;
   if (num_actions == 0)
      return;
   
   if ((!w->file) || (!FEH_FILE(w->file->data))
       || (!FEH_FILE(w->file->data)->filename))
      D_RETURN_(4);

   if (!fn)
   {
      memset(atab, 0, sizeof(atab));
      if (w->full_screen)
         fn = gib_imlib_load_font(DEFAULT_FONT_BIG);
      else
         fn = gib_imlib_load_font(DEFAULT_FONT);
   }

   if (!fn)
   {
      weprintf("Couldn't load font for actions printing");
      D_RETURN_(4);
   }


   gib_imlib_get_text_size(fn, "defined actions:", NULL, &tw, &th,
                           IMLIB_TEXT_TO_RIGHT);
// Check for the widest line
   max_tw = tw; 
   for (i=0;opt.actions[i];i++) {
   gib_imlib_get_text_size(fn, opt.actions[i], NULL, &tw, &th,
                           IMLIB_TEXT_TO_RIGHT);
   	if (tw>max_tw) {
	   max_tw = tw;
	}
   }

   tw = max_tw;
   tw += 3;
   th += 3;
   line_th = th;
   th = (th*num_actions)+line_th;

   im = imlib_create_image(tw, th);
   if (!im)
      eprintf("Couldn't create image. Out of memory?");

   gib_imlib_image_set_has_alpha(im, 1);
   gib_imlib_apply_color_modifier_to_rectangle(im, 0, 0, tw, th,
                                               NULL, NULL, NULL, atab);
   gib_imlib_image_fill_rectangle(im, 0, 0, tw, th, 0, 0, 0, 0);
   
   gib_imlib_text_draw(im, fn, NULL, 1, 1, "defined actions:",
                       IMLIB_TEXT_TO_RIGHT, 0, 0, 0, 255);
   gib_imlib_text_draw(im, fn, NULL, 2, 2, "defined actions:",
                       IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);

   for(i=0;i<num_actions;i++)
   {
//    compose a line containing an index, a colon followed by the
//    action.
      char index[1];
      char line[strlen(opt.actions[i])+5];
      sprintf(index, "%d", i);
      strcpy(line, index);
      strcat(line, ": ");
      strcat(line, opt.actions[i]);

      gib_imlib_text_draw(im, fn, NULL, 2, ((i+1)*line_th)+2, line,
                          IMLIB_TEXT_TO_RIGHT, 0, 0, 0, 255);
      gib_imlib_text_draw(im, fn, NULL, 1, ((i+1)*line_th)+1, line,
                          IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);
      free(line);
   }

   gib_imlib_render_image_on_drawable(w->bg_pmap, im, 0, 0, 1, 1, 0);

   gib_imlib_free_image_and_decache(im);
   D_RETURN_(4);
}