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