You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

97 lines
3.0 KiB

  1. /* Copyright (C) 2001-2017 Peter Selinger.
  2. * This file is part of Potrace. It is free software and it is covered
  3. * by the GNU General Public License. See the file COPYING for details. */
  4. /* operations on potrace_progress_t objects, which are defined in
  5. * potracelib.h. Note: the code attempts to minimize runtime overhead
  6. * when no progress monitoring was requested. It also tries to
  7. * minimize excessive progress calculations beneath the "epsilon"
  8. * threshold. */
  9. #ifndef PROGRESS_H
  10. #define PROGRESS_H
  11. /* structure to hold progress bar callback data */
  12. struct progress_s
  13. {
  14. void ( * callback )( double progress, void* privdata ); /* callback fn */
  15. void* data; /* callback function's private data */
  16. double min, max; /* desired range of progress, e.g. 0.0 to 1.0 */
  17. double epsilon; /* granularity: can skip smaller increments */
  18. double b; /* upper limit of subrange in superrange units */
  19. double d_prev; /* previous value of d */
  20. };
  21. typedef struct progress_s progress_t;
  22. /* notify given progress object of current progress. Note that d is
  23. * given in the 0.0-1.0 range, which will be scaled and translated to
  24. * the progress object's range. */
  25. static inline void progress_update( double d, progress_t* prog )
  26. {
  27. double d_scaled;
  28. if( prog != NULL && prog->callback != NULL )
  29. {
  30. d_scaled = prog->min * ( 1 - d ) + prog->max * d;
  31. if( d == 1.0 || d_scaled >= prog->d_prev + prog->epsilon )
  32. {
  33. prog->callback( prog->min * ( 1 - d ) + prog->max * d, prog->data );
  34. prog->d_prev = d_scaled;
  35. }
  36. }
  37. }
  38. /* start a subrange of the given progress object. The range is
  39. * narrowed to [a..b], relative to 0.0-1.0 coordinates. If new range
  40. * is below granularity threshold, disable further subdivisions. */
  41. static inline void progress_subrange_start( double a,
  42. double b,
  43. const progress_t* prog,
  44. progress_t* sub )
  45. {
  46. double min, max;
  47. if( prog == NULL || prog->callback == NULL )
  48. {
  49. sub->callback = NULL;
  50. return;
  51. }
  52. min = prog->min * ( 1 - a ) + prog->max * a;
  53. max = prog->min * ( 1 - b ) + prog->max * b;
  54. if( max - min < prog->epsilon )
  55. {
  56. sub->callback = NULL; /* no further progress info in subrange */
  57. sub->b = b;
  58. return;
  59. }
  60. sub->callback = prog->callback;
  61. sub->data = prog->data;
  62. sub->epsilon = prog->epsilon;
  63. sub->min = min;
  64. sub->max = max;
  65. sub->d_prev = prog->d_prev;
  66. }
  67. static inline void progress_subrange_end( progress_t* prog, progress_t* sub )
  68. {
  69. if( prog != NULL && prog->callback != NULL )
  70. {
  71. if( sub->callback == NULL )
  72. {
  73. progress_update( sub->b, prog );
  74. }
  75. else
  76. {
  77. prog->d_prev = sub->d_prev;
  78. }
  79. }
  80. }
  81. #endif /* PROGRESS_H */