97 lines
3.1 KiB
C
97 lines
3.1 KiB
C
|
/* 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 */
|