mirror of https://github.com/GNOME/gimp.git
libgimpwidgets: add ratio expressions to eevl
Ratio expressions have the form 'x : y' (the ':' operator has the highest precedence for a binary operator, and is left-associative). Given a reference value 'a', the expression evaluates to 'a * (x / y)'. Ratio expressions can be controlled by the caller by: - Enabling or disabling them: They're meant to be used when the eevl servers two paired entries, and can be disabled otherwise. - Setting the reference value: That's normally the value of the "other" entry of the pair--the one not currently being evaluated. - Inverting the ratios: Normally, one entry refers to the antecedent term of the ratio, and the other entry refers to the consequent term of the ratio. When evaluating the latter one, the ratio should be inverted.
This commit is contained in:
parent
7362d47922
commit
6caae9c53b
|
@ -40,7 +40,9 @@
|
|||
* expression ::= term { ('+' | '-') term }* |
|
||||
* <empty string> ;
|
||||
*
|
||||
* term ::= signed factor { ( '*' | '/' ) signed factor }* ;
|
||||
* term ::= ratio { ( '*' | '/' ) ratio }* ;
|
||||
*
|
||||
* ratio ::= signed factor { ':' signed factor }* ;
|
||||
*
|
||||
* signed factor ::= ( '+' | '-' )? factor ;
|
||||
*
|
||||
|
@ -123,6 +125,7 @@ static void gimp_eevl_init (GimpEevl
|
|||
static GimpEevlQuantity gimp_eevl_complete (GimpEevl *eva);
|
||||
static GimpEevlQuantity gimp_eevl_expression (GimpEevl *eva);
|
||||
static GimpEevlQuantity gimp_eevl_term (GimpEevl *eva);
|
||||
static GimpEevlQuantity gimp_eevl_ratio (GimpEevl *eva);
|
||||
static GimpEevlQuantity gimp_eevl_signed_factor (GimpEevl *eva);
|
||||
static GimpEevlQuantity gimp_eevl_factor (GimpEevl *eva);
|
||||
static gboolean gimp_eevl_accept (GimpEevl *eva,
|
||||
|
@ -307,30 +310,61 @@ static GimpEevlQuantity
|
|||
gimp_eevl_term (GimpEevl *eva)
|
||||
{
|
||||
gboolean division;
|
||||
GimpEevlQuantity evaluated_signed_factors;
|
||||
GimpEevlQuantity evaluated_ratios;
|
||||
|
||||
evaluated_signed_factors = gimp_eevl_signed_factor (eva);
|
||||
evaluated_ratios = gimp_eevl_ratio (eva);
|
||||
|
||||
for (division = FALSE;
|
||||
gimp_eevl_accept (eva, '*', NULL) ||
|
||||
(division = gimp_eevl_accept (eva, '/', NULL));
|
||||
division = FALSE)
|
||||
{
|
||||
GimpEevlQuantity new_signed_factor = gimp_eevl_signed_factor (eva);
|
||||
GimpEevlQuantity new_ratio = gimp_eevl_ratio (eva);
|
||||
|
||||
if (division)
|
||||
{
|
||||
evaluated_signed_factors.value /= new_signed_factor.value;
|
||||
evaluated_signed_factors.dimension -= new_signed_factor.dimension;
|
||||
|
||||
evaluated_ratios.value /= new_ratio.value;
|
||||
evaluated_ratios.dimension -= new_ratio.dimension;
|
||||
}
|
||||
else
|
||||
{
|
||||
evaluated_signed_factors.value *= new_signed_factor.value;
|
||||
evaluated_signed_factors.dimension += new_signed_factor.dimension;
|
||||
evaluated_ratios.value *= new_ratio.value;
|
||||
evaluated_ratios.dimension += new_ratio.dimension;
|
||||
}
|
||||
}
|
||||
|
||||
return evaluated_ratios;
|
||||
}
|
||||
|
||||
static GimpEevlQuantity
|
||||
gimp_eevl_ratio (GimpEevl *eva)
|
||||
{
|
||||
GimpEevlQuantity evaluated_signed_factors;
|
||||
|
||||
if (! eva->options.ratio_expressions)
|
||||
return gimp_eevl_signed_factor (eva);
|
||||
|
||||
evaluated_signed_factors = gimp_eevl_signed_factor (eva);
|
||||
|
||||
while (gimp_eevl_accept (eva, ':', NULL))
|
||||
{
|
||||
GimpEevlQuantity new_signed_factor = gimp_eevl_signed_factor (eva);
|
||||
|
||||
if (eva->options.ratio_invert)
|
||||
{
|
||||
GimpEevlQuantity temp;
|
||||
|
||||
temp = evaluated_signed_factors;
|
||||
evaluated_signed_factors = new_signed_factor;
|
||||
new_signed_factor = temp;
|
||||
}
|
||||
|
||||
evaluated_signed_factors.value *= eva->options.ratio_quantity.value /
|
||||
new_signed_factor.value;
|
||||
evaluated_signed_factors.dimension += eva->options.ratio_quantity.dimension -
|
||||
new_signed_factor.dimension;
|
||||
}
|
||||
|
||||
return evaluated_signed_factors;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,18 +59,29 @@ typedef gboolean (* GimpEevlUnitResolverProc) (const gchar *identifier,
|
|||
* GimpEevlOptions:
|
||||
* @unit_resolver_proc: Unit resolver callback.
|
||||
* @data: Data passed to unit resolver.
|
||||
* @ratio_expressions: Allow ratio expressions
|
||||
* @ratio_invert: Invert ratios
|
||||
* @ratio_quantity: Quantity to multiply ratios by
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
GimpEevlUnitResolverProc unit_resolver_proc;
|
||||
gpointer data;
|
||||
|
||||
gboolean ratio_expressions;
|
||||
gboolean ratio_invert;
|
||||
GimpEevlQuantity ratio_quantity;
|
||||
} GimpEevlOptions;
|
||||
|
||||
#define GIMP_EEVL_OPTIONS_INIT \
|
||||
((const GimpEevlOptions) \
|
||||
{ \
|
||||
.unit_resolver_proc = NULL, \
|
||||
.data = NULL \
|
||||
.data = NULL, \
|
||||
\
|
||||
.ratio_expressions = FALSE, \
|
||||
.ratio_invert = FALSE, \
|
||||
.ratio_quantity = {0.0, 0} \
|
||||
})
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue