File indexing completed on 2024-12-22 04:04:14

0001 /* Copyright (C) 2001-2019 Peter Selinger.
0002    This file is part of Potrace. It is free software and it is covered
0003    by the GNU General Public License. See the file COPYING for details. */
0004 
0005 /* operations on potrace_progress_t objects, which are defined in
0006    potracelib.h. Note: the code attempts to minimize runtime overhead
0007    when no progress monitoring was requested. It also tries to
0008    minimize excessive progress calculations beneath the "epsilon"
0009    threshold. */
0010 
0011 #ifndef PROGRESS_H
0012 #define PROGRESS_H
0013 
0014 /* structure to hold progress bar callback data */
0015 struct progress_s {
0016   void (*callback)(double progress, void *privdata); /* callback fn */
0017   void *data;          /* callback function's private data */
0018   double min, max;     /* desired range of progress, e.g. 0.0 to 1.0 */
0019   double epsilon;      /* granularity: can skip smaller increments */
0020   double b;            /* upper limit of subrange in superrange units */
0021   double d_prev;       /* previous value of d */
0022 };
0023 typedef struct progress_s progress_t;
0024 
0025 /* notify given progress object of current progress. Note that d is
0026    given in the 0.0-1.0 range, which will be scaled and translated to
0027    the progress object's range. */
0028 static inline void progress_update(double d, progress_t *prog) {
0029   double d_scaled;
0030 
0031   if (prog != NULL && prog->callback != NULL) {
0032     d_scaled = prog->min * (1-d) + prog->max * d;
0033     if (d == 1.0 || d_scaled >= prog->d_prev + prog->epsilon) {
0034       prog->callback(prog->min * (1-d) + prog->max * d, prog->data);
0035       prog->d_prev = d_scaled;
0036     }
0037   }
0038 }
0039 
0040 /* start a subrange of the given progress object. The range is
0041    narrowed to [a..b], relative to 0.0-1.0 coordinates. If new range
0042    is below granularity threshold, disable further subdivisions. */
0043 static inline void progress_subrange_start(double a, double b, const progress_t *prog, progress_t *sub) {
0044   double min, max;
0045 
0046   if (prog == NULL || prog->callback == NULL) {
0047     sub->callback = NULL;
0048     return;
0049   }
0050 
0051   min = prog->min * (1-a) + prog->max * a;
0052   max = prog->min * (1-b) + prog->max * b;
0053 
0054   if (max - min < prog->epsilon) {
0055     sub->callback = NULL;    /* no further progress info in subrange */
0056     sub->b = b;
0057     return;
0058   }
0059   sub->callback = prog->callback;
0060   sub->data = prog->data;
0061   sub->epsilon = prog->epsilon;
0062   sub->min = min;
0063   sub->max = max;
0064   sub->d_prev = prog->d_prev;
0065   return;
0066 }
0067 
0068 static inline void progress_subrange_end(progress_t *prog, progress_t *sub) {
0069   if (prog != NULL && prog->callback != NULL) {
0070     if (sub->callback == NULL) {
0071       progress_update(sub->b, prog);
0072     } else {
0073       prog->d_prev = sub->d_prev;
0074     }
0075   }    
0076 }
0077 
0078 #endif /* PROGRESS_H */
0079