[goffice] Fix rendering of # ???/??? format. [#656043]
- From: Andreas J. Guelzow <guelzow src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] Fix rendering of # ???/??? format. [#656043]
- Date: Thu, 25 Aug 2011 07:45:48 +0000 (UTC)
commit 8c824072ab9eca090ff817f18a768a437f742bef
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date: Thu Aug 25 01:45:18 2011 -0600
Fix rendering of # ???/??? format. [#656043]
2011-08-24 Andreas J. Guelzow <aguelzow pyrshep ca>
* goffice/gtk/go-format-sel.c (study_format): scientific number
formatting with min_digits =0 and =1 are effectively indistinguishable
(fmt_dialog_enable_widgets): set the range of the F_EXP_DIGITS widget
depending on format_type
* goffice/utils/go-format.c (go_format_parse_number_new_1): add argument
and change all callers
(go_format_parse_number_fraction): write OP_NUM_FRACTION_BLANK_WHOLE if
appropriate
(blank_characters): new
(go_format_execute): use blank_characters and handle OP_NUM_FRACTION_BLANK_WHOLE
(go_format_generate_fraction_str): write full numerator
(cnt_digits): new
ChangeLog | 15 ++++
NEWS | 1 +
goffice/gtk/go-format-sel.c | 11 ++-
goffice/utils/go-format.c | 197 ++++++++++++++++++++++++++++---------------
4 files changed, 150 insertions(+), 74 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 6a5150f..cb115d5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
2011-08-24 Andreas J. Guelzow <aguelzow pyrshep ca>
+ * goffice/gtk/go-format-sel.c (study_format): scientific number
+ formatting with min_digits =0 and =1 are effectively indistinguishable
+ (fmt_dialog_enable_widgets): set the range of the F_EXP_DIGITS widget
+ depending on format_type
+ * goffice/utils/go-format.c (go_format_parse_number_new_1): add argument
+ and change all callers
+ (go_format_parse_number_fraction): write OP_NUM_FRACTION_BLANK_WHOLE if
+ appropriate
+ (blank_characters): new
+ (go_format_execute): use blank_characters and handle OP_NUM_FRACTION_BLANK_WHOLE
+ (go_format_generate_fraction_str): write full numerator
+ (cnt_digits): new
+
+2011-08-24 Andreas J. Guelzow <aguelzow pyrshep ca>
+
* goffice/gtk/go-format-sel.c (study_format): the fraction selector
interface handles min_digits.
diff --git a/NEWS b/NEWS
index 1787f27..22adae1 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,7 @@ Andreas:
* Extend encoding specification from file-openers to plugin services.
* Improve the scientific number formats selector. [#657187][#623847]
* Improve fraction format selector. [#117215]
+ * Fix rendering of # ???/??? format. [#656043]
Jean:
* Port to gtk+-3.0.
diff --git a/goffice/gtk/go-format-sel.c b/goffice/gtk/go-format-sel.c
index ac96620..1d9ca19 100644
--- a/goffice/gtk/go-format-sel.c
+++ b/goffice/gtk/go-format-sel.c
@@ -741,14 +741,17 @@ stays:
break;
case F_EXP_DIGITS:
- if (page == GO_FORMAT_FRACTION)
+ if (page == GO_FORMAT_FRACTION) {
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (w), 0, 30);
gtk_spin_button_set_value
(GTK_SPIN_BUTTON (w),
gfs->format.details.numerator_min_digits);
- else
+ } else {
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (w), 1, 10);
gtk_spin_button_set_value
(GTK_SPIN_BUTTON (w),
gfs->format.details.exponent_digits);
+ }
break;
case F_ENGINEERING_BUTTON:
@@ -1021,9 +1024,7 @@ study_format (GOFormat const *fmt, GOFormatDetails *details)
exact = FALSE;
if ((details->family != GO_FORMAT_FRACTION)
- && ((details->min_digits > 1) ||
- (details->family != GO_FORMAT_SCIENTIFIC
- && details->min_digits == 0)))
+ && (details->min_digits > 1))
exact = FALSE;
}
diff --git a/goffice/utils/go-format.c b/goffice/utils/go-format.c
index 4603801..5d1bc76 100644
--- a/goffice/utils/go-format.c
+++ b/goffice/utils/go-format.c
@@ -188,6 +188,7 @@ typedef enum {
OP_NUM_FRACTION_NOMINATOR,
OP_NUM_FRACTION_DENOMINATOR,
OP_NUM_FRACTION_BLANK,
+ OP_NUM_FRACTION_BLANK_WHOLE,
#ifdef ALLOW_PI_SLASH
OP_NUM_FRACTION_SCALE_PI,
OP_NUM_FRACTION_SIMPLIFY_PI,
@@ -1521,7 +1522,8 @@ comma_is_thousands (const char *str)
static gboolean
go_format_parse_number_new_1 (GString *prg, GOFormatParseState *pstate,
int tno_start, int tno_end,
- int E_part, int frac_part)
+ int E_part, int frac_part,
+ gboolean *inhibit_blank)
{
int decimals = 0;
int whole_digits = 0;
@@ -1535,6 +1537,7 @@ go_format_parse_number_new_1 (GString *prg, GOFormatParseState *pstate,
int i;
int tno_numstart = -1;
int force_zero_pos = frac_part == 3 ? pstate->force_zero_pos : INT_MAX;
+ gboolean inhibit_b = FALSE;
for (i = tno_start; i < tno_end; i++) {
const GOFormatParseItem *ti = &GET_TOKEN(i);
@@ -1552,7 +1555,10 @@ go_format_parse_number_new_1 (GString *prg, GOFormatParseState *pstate,
whole_part = FALSE;
break;
- case '0': case '?': case '#':
+ case '0':
+ inhibit_b = TRUE;
+ /* no break */
+ case '?': case '#':
if (first_digit_pos == -1)
first_digit_pos = i;
if (whole_part)
@@ -1680,6 +1686,9 @@ go_format_parse_number_new_1 (GString *prg, GOFormatParseState *pstate,
}
pstate->scale = scale;
+
+ if (inhibit_blank)
+ *inhibit_blank = inhibit_b;
return TRUE;
error:
@@ -1696,7 +1705,7 @@ go_format_parse_number_plain (GOFormatParseState *pstate)
if (!go_format_parse_number_new_1 (prg, pstate,
0, pstate->tokens->len,
- 0, 0))
+ 0, 0, NULL))
return NULL;
handle_fill (prg, pstate);
@@ -1761,7 +1770,7 @@ go_format_parse_number_E (GOFormatParseState *pstate)
if (!go_format_parse_number_new_1 (prg, pstate,
0, pstate->tno_E,
- 1, 0))
+ 1, 0, NULL))
return NULL;
ADD_OP (OP_NUM_VAL_EXPONENT);
@@ -1779,7 +1788,7 @@ go_format_parse_number_E (GOFormatParseState *pstate)
if (!go_format_parse_number_new_1 (prg, pstate,
tno_exp_start, tno_end,
- 2, 0))
+ 2, 0, NULL))
return NULL;
#ifdef ALLOW_EE_MARKUP
@@ -1814,6 +1823,7 @@ go_format_parse_number_fraction (GOFormatParseState *pstate)
gboolean explicit_denom = FALSE;
int denominator_digits = 0;
gboolean inhibit_blank = FALSE;
+ gboolean inhibit_blank_whole = TRUE;
int scale = 0;
#ifdef ALLOW_PI_SLASH
gboolean pi_scale = (tno_slash >= 2 &&
@@ -1935,7 +1945,7 @@ go_format_parse_number_fraction (GOFormatParseState *pstate)
ADD_OP (OP_NUM_FRACTION_WHOLE);
if (!go_format_parse_number_new_1 (prg, pstate,
0, tno_endwhole + 1,
- 0, 1))
+ 0, 1, &inhibit_blank_whole))
return NULL;
scale += pstate->scale;
}
@@ -1945,7 +1955,7 @@ go_format_parse_number_fraction (GOFormatParseState *pstate)
if (!go_format_parse_number_new_1 (prg, pstate,
tno_endwhole + 1,
pi_scale ? tno_slash - 2 :tno_slash,
- 0, 2))
+ 0, 2, NULL))
return NULL;
scale += pstate->scale;
@@ -1957,13 +1967,15 @@ go_format_parse_number_fraction (GOFormatParseState *pstate)
ADD_OP (OP_NUM_FRACTION_DENOMINATOR);
if (!go_format_parse_number_new_1 (prg, pstate,
tno_slash + 1, tno_suffix,
- 0, 3))
+ 0, 3, NULL))
return NULL;
scale += pstate->scale;
if (!inhibit_blank)
ADD_OP (OP_NUM_FRACTION_BLANK);
+ if (!inhibit_blank_whole)
+ ADD_OP (OP_NUM_FRACTION_BLANK_WHOLE);
#ifdef ALLOW_PI_SLASH
- else if (pi_scale)
+ if (inhibit_blank && pi_scale)
ADD_OP (OP_NUM_FRACTION_SIMPLIFY_PI);
#endif
@@ -2316,6 +2328,7 @@ go_format_dump_program (const guchar *prg)
REGULAR(OP_NUM_FRACTION_NOMINATOR);
REGULAR(OP_NUM_FRACTION_DENOMINATOR);
REGULAR(OP_NUM_FRACTION_BLANK);
+ REGULAR(OP_NUM_FRACTION_BLANK_WHOLE);
#ifdef ALLOW_PI_SLASH
REGULAR(OP_NUM_FRACTION_SCALE_PI);
REGULAR(OP_NUM_FRACTION_SIMPLIFY_PI);
@@ -2449,6 +2462,48 @@ SUFFIX(printf_engineering) (GString *dst, DOUBLE val, int n, int wd)
g_string_append_printf (dst, "E%+d", exponent);
}
+#ifdef DEFINE_COMMON
+static int
+blank_characters (GString *dst, PangoAttrList *attrs, int start, int length,
+ PangoLayout *layout)
+{
+ int count = 0;
+ /* We have layouts that have no fontmap set, we need to avoid them */
+ if (layout && pango_context_get_font_map (pango_layout_get_context (layout))) {
+ GList *plist, *l;
+ plist = pango_itemize (pango_layout_get_context (layout),
+ dst->str,
+ start,
+ length,
+ attrs,
+ NULL);
+ for (l = plist; l != NULL; l = l->next) {
+ PangoItem *pi = l->data;
+ PangoGlyphString *glyphs = pango_glyph_string_new ();
+ PangoAttribute *attr;
+ PangoRectangle ink_rect;
+ PangoRectangle logical_rect;
+
+ pango_shape (dst->str + start, length, &pi->analysis, glyphs);
+ pango_glyph_string_extents (glyphs,
+ pi->analysis.font,
+ &ink_rect,
+ &logical_rect);
+ pango_glyph_string_free (glyphs);
+
+ attr = pango_attr_shape_new (&ink_rect, &logical_rect);
+ attr->start_index = start + count;
+ attr->end_index = start + count + 1;
+ pango_attr_list_insert (attrs, attr);
+ count++;
+ }
+ go_list_free_custom (plist, (GFreeFunc) pango_item_free);
+ }
+ return count;
+}
+#endif
+
+
#define INSERT_MINUS(pos) do { \
@@ -2491,23 +2546,23 @@ SUFFIX(go_format_execute) (PangoLayout *layout, GString *dst,
int exponent = 0;
struct {
DOUBLE w, n, d;
- gsize nominator_start, denominator_start;
- } fraction;
+ gsize whole_start, nominator_start, denominator_start;
+ gboolean blanked;
+ } fraction = {0., 0., 0., 0, 0, 0, FALSE};
char *oldlocale = NULL;
+ PangoAttrList *attrs = NULL;
+
#ifdef ALLOW_EE_MARKUP
int mantissa_start = -1;
int special_mantissa = INT_MAX;
- PangoAttrList *attrs = NULL;
GSList *markup_stack = NULL;
+#endif
if (layout) {
attrs = pango_attr_list_copy (pango_layout_get_attributes (layout));
if (attrs == NULL)
attrs = pango_attr_list_new ();
}
-#endif
-
- memset (&fraction, 0, sizeof (fraction));
while (1) {
GOFormatOp op = *prg++;
@@ -2516,10 +2571,12 @@ SUFFIX(go_format_execute) (PangoLayout *layout, GString *dst,
case OP_END:
if (layout) {
pango_layout_set_text (layout, dst->str, -1);
+ if (attrs) {
+ pango_layout_set_attributes (layout, attrs);
+ pango_attr_list_unref (attrs);
+ attrs = NULL;
+ }
#ifdef ALLOW_EE_MARKUP
-
- pango_layout_set_attributes (layout, attrs);
- pango_attr_list_unref (attrs);
g_slist_free (markup_stack);
#endif
}
@@ -2943,8 +3000,9 @@ SUFFIX(go_format_execute) (PangoLayout *layout, GString *dst,
case OP_NUM_MOVETO_ONES: {
numi = dotpos;
- /* Ignore the zero in "0.xxx" */
- if (numi == 1 && numtxt->str[0] == '0' && numtxt->str[dotpos] != 0)
+ /* Ignore the zero in "0.xxx" or "0 xx/xx" */
+ if (numi == 1 && numtxt->str[0] == '0' &&
+ numtxt->str[dotpos] != 0)
numi--;
numpos = dst->len;
break;
@@ -3150,6 +3208,7 @@ SUFFIX(go_format_execute) (PangoLayout *layout, GString *dst,
#endif
case OP_NUM_FRACTION_WHOLE:
+ fraction.whole_start = dst->len;
val = fraction.w;
break;
@@ -3171,48 +3230,21 @@ SUFFIX(go_format_execute) (PangoLayout *layout, GString *dst,
if (fraction.n == 0) {
/* Replace all added characters by spaces of the right length. */
- char const *f = dst->str + fraction.nominator_start;
- gsize chars = g_utf8_strlen (f, -1);
+ char const *f;
+ gsize chars;
- if (chars > 0) {
- /* We have layouts that have no fontmap set, we need to avoid them */
- if (layout && pango_context_get_font_map (pango_layout_get_context (layout))) {
- guint start = fraction.nominator_start;
- GList *plist, *l;
- gint length = dst->len - fraction.nominator_start;
- plist = pango_itemize (pango_layout_get_context (layout),
- dst->str,
- f - dst->str,
- length,
- attrs,
- NULL);
- chars = 0;
- for (l = plist; l != NULL; l = l->next) {
- PangoItem *pi = l->data;
- PangoGlyphString *glyphs = pango_glyph_string_new ();
- PangoAttribute *attr;
- PangoRectangle ink_rect;
- PangoRectangle logical_rect;
-
- pango_shape (f, length, &pi->analysis, glyphs);
- pango_glyph_string_extents (glyphs,
- pi->analysis.font,
- &ink_rect,
- &logical_rect);
- pango_glyph_string_free (glyphs);
-
- attr = pango_attr_shape_new (&ink_rect, &logical_rect);
- attr->start_index = start;
- attr->end_index = start + 1;
- pango_attr_list_insert (attrs, attr);
- start++;
- chars++;
- }
- go_list_free_custom (plist, (GFreeFunc) pango_item_free);
- }
+ f = dst->str + fraction.nominator_start;
+ chars = g_utf8_strlen (f, -1);
- memset (dst->str + fraction.nominator_start, ' ', chars);
- g_string_truncate (dst, fraction.nominator_start + chars);
+ if (chars > 0) {
+ int count = blank_characters (dst, attrs, fraction.nominator_start,
+ dst->len - fraction.nominator_start, layout);
+
+ if (count == 0)
+ count = chars;
+ memset (dst->str + fraction.nominator_start, ' ', count);
+ g_string_truncate (dst, fraction.nominator_start + count);
+ fraction.blanked = TRUE;
}
}
@@ -3262,6 +3294,14 @@ SUFFIX(go_format_execute) (PangoLayout *layout, GString *dst,
break;
}
+ case OP_NUM_FRACTION_BLANK_WHOLE:
+ if (!fraction.blanked) {
+ char *zero = dst->str + fraction.whole_start;
+ if (*zero == '0')
+ *zero = ' ';
+ }
+ break;
+
#ifdef ALLOW_PI_SLASH
case OP_NUM_FRACTION_SIMPLIFY_PI:
if (fraction.n != 0 && fraction.d == 1) {
@@ -5266,11 +5306,30 @@ go_format_generate_scientific_str (GString *dst, GOFormatDetails const *details)
#endif
#ifdef DEFINE_COMMON
+static int
+cnt_digits (int d)
+{
+ int cnt = 0;
+
+ while (d > 0) {
+ cnt++;
+ d /= 10;
+ }
+
+ return cnt;
+}
+#endif
+
+#ifdef DEFINE_COMMON
static void
go_format_generate_fraction_str (GString *dst, GOFormatDetails const *details)
{
/* Maximum not terribly important. */
int numerator_min_digits = CLAMP (details->numerator_min_digits, 0, 30);
+ int denominator_max_digits = CLAMP (details->denominator_max_digits, 1, 30);
+ int denominator_min_digits = CLAMP (details->denominator_min_digits, 0, denominator_max_digits);
+ int denominator = CLAMP (details->denominator, 2, G_MAXINT);
+ int num_digits;
if (details->split_fraction) {
/* Maximum not terribly important. */
@@ -5281,26 +5340,26 @@ go_format_generate_fraction_str (GString *dst, GOFormatDetails const *details)
g_string_append_c (dst, '#');
g_string_append_c (dst, ' ');
}
+
+ if (details->automatic_denominator)
+ num_digits = denominator_max_digits - numerator_min_digits;
+ else
+ num_digits = cnt_digits (denominator) - numerator_min_digits;
+ if (num_digits > 0)
+ go_string_append_c_n (dst, '?', num_digits);
if (numerator_min_digits > 0)
go_string_append_c_n (dst, '0', numerator_min_digits);
- else
- g_string_append_c (dst, '?');
-
+
g_string_append_c (dst, '/');
if (details->automatic_denominator) {
- int denominator_max_digits = CLAMP (details->denominator_max_digits, 1, 30);
- int denominator_min_digits = CLAMP (details->denominator_min_digits,
- 0, denominator_max_digits);
go_string_append_c_n (dst, '?',
denominator_max_digits - denominator_min_digits);
go_string_append_c_n (dst, '0',
denominator_min_digits);
- } else {
- int denominator = CLAMP (details->denominator, 2, G_MAXINT);
+ } else
g_string_append_printf (dst, "%d", denominator);
- }
}
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]