summaryrefslogtreecommitdiff
path: root/potrace/progress.h
diff options
context:
space:
mode:
Diffstat (limited to 'potrace/progress.h')
-rw-r--r--potrace/progress.h96
1 files changed, 96 insertions, 0 deletions
diff --git a/potrace/progress.h b/potrace/progress.h
new file mode 100644
index 0000000..5010481
--- /dev/null
+++ b/potrace/progress.h
@@ -0,0 +1,96 @@
+/* Copyright (C) 2001-2007 Peter Selinger.
+ * This file is part of Potrace. It is free software and it is covered
+ * by the GNU General Public License. See the file COPYING for details. */
+
+/* operations on potrace_progress_t objects, which are defined in
+ * potracelib.h. Note: the code attempts to minimize runtime overhead
+ * when no progress monitoring was requested. It also tries to
+ * minimize excessive progress calculations beneath the "epsilon"
+ * threshold. */
+
+#ifndef PROGRESS_H
+#define PROGRESS_H
+
+/* structure to hold progress bar callback data */
+struct progress_s
+{
+ void (* callback)( double progress, void* privdata ); /* callback fn */
+ void* data; /* callback function's private data */
+ double min, max; /* desired range of progress, e.g. 0.0 to 1.0 */
+ double epsilon; /* granularity: can skip smaller increments */
+ double b; /* upper limit of subrange in superrange units */
+ double d_prev; /* previous value of d */
+};
+typedef struct progress_s progress_t;
+
+/* notify given progress object of current progress. Note that d is
+ * given in the 0.0-1.0 range, which will be scaled and translated to
+ * the progress object's range. */
+static inline void progress_update( double d, progress_t* prog )
+{
+ double d_scaled;
+
+ if( prog->callback != NULL )
+ {
+ d_scaled = prog->min * (1 - d) + prog->max * d;
+ if( d == 1.0 || d_scaled >= prog->d_prev + prog->epsilon )
+ {
+ prog->callback( prog->min * (1 - d) + prog->max * d, prog->data );
+ prog->d_prev = d_scaled;
+ }
+ }
+}
+
+
+/* start a subrange of the given progress object. The range is
+ * narrowed to [a..b], relative to 0.0-1.0 coordinates. If new range
+ * is below granularity threshold, disable further subdivisions. */
+static inline void progress_subrange_start( double a,
+ double b,
+ const progress_t* prog,
+ progress_t* sub )
+{
+ double min, max;
+
+ if( prog->callback == NULL )
+ {
+ sub->callback = NULL;
+ return;
+ }
+
+ min = prog->min * (1 - a) + prog->max * a;
+ max = prog->min * (1 - b) + prog->max * b;
+
+ if( max - min < prog->epsilon )
+ {
+ sub->callback = NULL; /* no further progress info in subrange */
+ sub->b = b;
+ return;
+ }
+ sub->callback = prog->callback;
+ sub->data = prog->data;
+ sub->epsilon = prog->epsilon;
+ sub->min = min;
+ sub->max = max;
+ sub->d_prev = prog->d_prev;
+ return;
+}
+
+
+static inline void progress_subrange_end( progress_t* prog, progress_t* sub )
+{
+ if( prog->callback != NULL )
+ {
+ if( sub->callback == NULL )
+ {
+ progress_update( sub->b, prog );
+ }
+ else
+ {
+ prog->d_prev = sub->d_prev;
+ }
+ }
+}
+
+
+#endif /* PROGRESS_H */