From 5cdb6271daece063aa5609b3d63e754d3db71de1 Mon Sep 17 00:00:00 2001 From: Glen Whitney Date: Wed, 18 Sep 2019 08:49:53 -0400 Subject: [PATCH] Add dim and italic attributes to style Closes #74 --- doc/teapot.lyx | 91 +++++++++++++++++++++++++++++++++++++++++++++- src/common/eval.c | 8 ++++ src/common/func.c | 15 +++++--- src/common/func.h | 2 + src/common/main.c | 38 ++++++++++++++----- src/common/main.h | 4 +- src/common/sheet.c | 35 ++---------------- src/common/sheet.h | 9 ++--- src/common/style.c | 8 ++++ src/common/style.h | 4 ++ src/common/token.c | 18 +++++++++ src/display.c | 27 ++++++++------ src/fteapot.fl | 23 ++++++++++-- 13 files changed, 213 insertions(+), 69 deletions(-) diff --git a/doc/teapot.lyx b/doc/teapot.lyx index e9f2b7a..d7ea182 100644 --- a/doc/teapot.lyx +++ b/doc/teapot.lyx @@ -3711,6 +3711,20 @@ teapot always uses the maximum precision internally for calculations. \end_layout +\begin_layout Subsubsection +Dim +\end_layout + +\begin_layout Standard +This attribute is a simple true-false flag set with +\family sans +dim() +\family default + that determines whether the cell value will be displayed with dim characters, + if possible. + It defaults to false. +\end_layout + \begin_layout Subsubsection Bold \end_layout @@ -3725,6 +3739,20 @@ bold It defaults to false. \end_layout +\begin_layout Subsubsection +Italic +\end_layout + +\begin_layout Standard +This attribute is a simple true-false flag set with +\family sans +italic() +\family default + that determines whether the cell value will be displayed in an italic font, + if possible. + It defaults to false. +\end_layout + \begin_layout Subsubsection Underline \end_layout @@ -7200,7 +7228,37 @@ x x \emph default radians. - +\end_layout + +\begin_layout Description + +\series medium +style +\emph on + +\begin_inset space ~ +\end_inset + + +\series default +\emph default +dim +\series medium +([bool +\emph on + +\begin_inset space ~ +\end_inset + +b +\emph default +]) +\series default + evaluates to a style token with the dim property set to +\emph on +b +\emph default +, which defaults to true (and no other fields set). \end_layout \begin_layout Description @@ -7793,6 +7851,37 @@ style \end_inset +\series default +\emph default +italic +\series medium +([bool +\emph on + +\begin_inset space ~ +\end_inset + +b +\emph default +]) +\series default + evaluates to a style token with the italic property set to +\emph on +b +\emph default +, which defaults to true (and no other fields set). +\end_layout + +\begin_layout Description + +\series medium +style +\emph on + +\begin_inset space ~ +\end_inset + + \series default \emph default justify diff --git a/src/common/eval.c b/src/common/eval.c index 216b65f..f6dacb0 100644 --- a/src/common/eval.c +++ b/src/common/eval.c @@ -262,10 +262,18 @@ Token tadd(Token l, Token r) result.u.style.transparent = r.u.style.transparent; result.u.style.transparent_set = true; } + if (!result.u.style.dim_set && r.u.style.dim_set) { + result.u.style.dim = r.u.style.dim; + result.u.style.dim_set = true; + } if (!result.u.style.bold_set && r.u.style.bold_set) { result.u.style.bold = r.u.style.bold; result.u.style.bold_set = true; } + if (!result.u.style.italic_set && r.u.style.italic_set) { + result.u.style.italic = r.u.style.italic; + result.u.style.italic_set = true; + } if (!result.u.style.underline_set && r.u.style.underline_set) { result.u.style.underline = r.u.style.underline; result.u.style.underline_set = true; diff --git a/src/common/func.c b/src/common/func.c index eec11c8..032d6b5 100644 --- a/src/common/func.c +++ b/src/common/func.c @@ -495,8 +495,8 @@ static Token disp_func(FunctionIdentifier self, int argc, const Token argv[]) return off; } -/* dim_func -- common implementation of the coordinate functions */ /*{{{*/ -static Token dim_func(FunctionIdentifier self, int argc, const Token argv[]) +/* coord_func -- common implementation of the coordinate functions */ /*{{{*/ +static Token coord_func(FunctionIdentifier self, int argc, const Token argv[]) { Dimensions dim = X; switch (self) { @@ -1139,7 +1139,9 @@ static Token floatfmt_func(FunctionIdentifier self, STYLEFLAGFUNC(shadowed) STYLEFLAGFUNC(transparent) +STYLEFLAGFUNC(dim) STYLEFLAGFUNC(bold) +STYLEFLAGFUNC(italic) STYLEFLAGFUNC(underline) /* accum_func -- common implementation of functions that accumulate all of @@ -1781,9 +1783,9 @@ Tfunc tfunc[]= [FUNC_UP] = { "up", disp_func, PREFIX_FUNC, FUNCT, 0 }, [FUNC_BELOW] = { "below", disp_func, PREFIX_FUNC, FUNCT, 0 }, [FUNC_ABOVE] = { "above", disp_func, PREFIX_FUNC, FUNCT, 0 }, - [FUNC_X] = { "x", dim_func, PREFIX_FUNC, FUNCT, 0 }, - [FUNC_Y] = { "y", dim_func, PREFIX_FUNC, FUNCT, 0 }, - [FUNC_Z] = { "z", dim_func, PREFIX_FUNC, FUNCT, 0 }, + [FUNC_X] = { "x", coord_func, PREFIX_FUNC, FUNCT, 0 }, + [FUNC_Y] = { "y", coord_func, PREFIX_FUNC, FUNCT, 0 }, + [FUNC_Z] = { "z", coord_func, PREFIX_FUNC, FUNCT, 0 }, [FUNC_FIND] = { "find", find_macro, PREFIX_FUNC, MACRO, 0 }, /* Evaluation control functions */ @@ -1811,6 +1813,7 @@ Tfunc tfunc[]= [FUNC_OPERATOR] = { "operator", self_func, PREFIX_FUNC, FUNCT, 0 }, [FUNC_STRING] = { "string", string_func, PREFIX_FUNC, FUNCT, 0 }, [FUNC_STYLE] = { "style", style_func, PREFIX_FUNC, FUNCT, 0 }, + /* Style functions */ [FUNC_PRECISION] = { "precision", precision_func, PREFIX_FUNC, FUNCT, 0 }, [FUNC_FOREGROUND] = { "foreground", aspect_func, PREFIX_FUNC, FUNCT, 0 }, @@ -1819,7 +1822,9 @@ Tfunc tfunc[]= [FUNC_FLOATFMT] = { "floatfmt", floatfmt_func, PREFIX_FUNC, FUNCT, 0 }, [FUNC_SHADOWED] = { "shadowed", shadowed_func, PREFIX_FUNC, FUNCT, 0 }, [FUNC_TRANSPARENT] = { "transparent", transparent_func,PREFIX_FUNC, FUNCT, 0 }, + [FUNC_DIM] = { "dim" , dim_func, PREFIX_FUNC, FUNCT, 0 }, [FUNC_BOLD] = { "bold", bold_func, PREFIX_FUNC, FUNCT, 0 }, + [FUNC_ITALIC] = { "italic", italic_func, PREFIX_FUNC, FUNCT, 0 }, [FUNC_UNDERLINE] = { "underline", underline_func, PREFIX_FUNC, FUNCT, 0 }, [FUNC_CENTER] = { "center", self_func, PREFIX_FUNC, FUNCT, 0 }, diff --git a/src/common/func.h b/src/common/func.h index 0816cfe..62b4574 100644 --- a/src/common/func.h +++ b/src/common/func.h @@ -49,6 +49,8 @@ typedef enum FUNC_FIX, + FUNC_DIM, FUNC_ITALIC, + N_FUNCTION_IDS } FunctionIdentifier; diff --git a/src/common/main.c b/src/common/main.c index c1defd9..546067f 100644 --- a/src/common/main.c +++ b/src/common/main.c @@ -435,20 +435,36 @@ static void do_attribute(Sheet *cursheet, Key action) break; } /*}}}*/ - /* 8 -- bold */ /*{{{*/ - case ADJUST_BOLD: + case ADJUST_DIM: /*{{{*/ { - int n; - - if (onecell) n = !(fs.bold); - else n = line_binary(_("Set block weight to:"), - _("rR)egular"), _("bB)old"), !(fs.bold)); + int n = !(fs.dim); + if (!onecell) n = line_binary(_("Set block brightness to:"), + _("rR)egular"), _("dD)im"), n); if (n >= 0) for (ALL_LOCS_IN_REGION(cursheet,w)) - changed = bold(cursheet, w, n) || changed; + changed = makedim(cursheet, w, n) || changed; break; - } - /*}}}*/ + } /*}}}*/ + case ADJUST_BOLD: /*{{{*/ + { + int n = !(fs.bold); + if (!onecell) n = line_binary(_("Set block weight to:"), + _("rR)egular"), _("bB)old"), n); + if (n >= 0) + for (ALL_LOCS_IN_REGION(cursheet,w)) + changed = embolden(cursheet, w, n) || changed; + break; + } /*}}}*/ + case ADJUST_ITALIC: /*{{{*/ + { + int n = !(fs.italic); + if (!onecell) n = line_binary(_("Set block font to:"), + _("rR)oman"), _("iI)talic"), n); + if (n >= 0) + for (ALL_LOCS_IN_REGION(cursheet,w)) + changed = italicize(cursheet, w, n) || changed; + break; + } /*}}}*/ /* 9 -- underline */ /*{{{*/ case ADJUST_UNDERLINE: { @@ -1331,7 +1347,9 @@ int do_sheetcmd(Sheet *cursheet, Key c, bool moveonly) case ADJUST_HEXACT: case ADJUST_PRECISION: case ADJUST_SHADOW: + case ADJUST_DIM: case ADJUST_BOLD: + case ADJUST_ITALIC: case ADJUST_UNDERLINE: case ADJUST_FOREGROUND: case ADJUST_BACKGROUND: diff --git a/src/common/main.h b/src/common/main.h index efc655d..96b5728 100644 --- a/src/common/main.h +++ b/src/common/main.h @@ -92,7 +92,9 @@ typedef enum ADJUST_HEXACT = -61, ADJUST_FOREGROUND = -62, ADJUST_BACKGROUND = -63, - K_EDIT_STYLE_EXPR = -64 + K_EDIT_STYLE_EXPR = -64, + ADJUST_DIM = -65, + ADJUST_ITALIC = -66 } Key; extern int do_sheetcmd(Sheet *cursheet, Key c, bool moveonly); diff --git a/src/common/sheet.c b/src/common/sheet.c index 9db442d..8880146 100644 --- a/src/common/sheet.c +++ b/src/common/sheet.c @@ -723,48 +723,18 @@ Style getstyle(Sheet *sheet, const Location at) return sty; } -/* getadjust -- get cell adjustment */ -Adjust getadjust(Sheet *sheet, const Location at) -{ - return getstyle(sheet, at).adjust; -} - /* shadowed -- is cell shadowed? */ bool shadowed(Sheet *sheet, const Location at) { return getstyle(sheet, at).shadowed; } -/* isbold -- is cell bold? */ -bool isbold(Sheet *sheet, const Location at) -{ - return getstyle(sheet, at).bold; -} - -/* getcolor -- a color associated to cell */ -ColorNum getcolor(Sheet *sheet, const Location at, ColorAspect aspect) -{ - return getstyle(sheet, at).aspect[aspect]; -} - -/* isunderline -- is cell underlined? */ -bool underlined(Sheet *sheet, const Location at) -{ - return getstyle(sheet, at).underline; -} - /* transparent -- is cell transparent? */ bool transparent(Sheet *sheet, const Location at) { return getstyle(sheet, at).transparent; } -/* getfltformat -- float format for numbers */ -FloatFormat getfltformat(Sheet *sheet, const Location at) -{ - return getstyle(sheet, at).fform; -} - /* getprecision -- get cell precision */ PrecisionLevel getprecision(Sheet *sheet, const Location at) { @@ -852,7 +822,9 @@ DEFSTYVAL(setprecision, PrecisionLevel, precision); } DEFSTYFLAG(shadow, shadowed); -DEFSTYFLAG(bold, bold); +DEFSTYFLAG(makedim, dim); +DEFSTYFLAG(embolden, bold); +DEFSTYFLAG(italicize, italic); DEFSTYFLAG(underline, underline); DEFSTYFLAG(maketrans, transparent); @@ -1026,6 +998,7 @@ const char *savetbl(Sheet *sheet, const char *name, int body, Style sw = getstyle(sheet,w); if (sw.shadowed && fputc_close('s',fp)==EOF) return strerror(errno); if (sw.bold && fputc_close('b',fp)==EOF) return strerror(errno); + /* FIXME: troff for italic/dim? */ if (sw.underline && fputc_close('u',fp)==EOF) return strerror(errno); switch (sw.adjust) { diff --git a/src/common/sheet.h b/src/common/sheet.h index 7048691..1542625 100644 --- a/src/common/sheet.h +++ b/src/common/sheet.h @@ -95,18 +95,15 @@ size_t printvalue(char *s, size_t size, size_t chars, StringFormat sf, FloatFormat ff, PrecisionLevel precision, Sheet *sheet, const Location at); Style getstyle(Sheet *sheet, const Location at); -Adjust getadjust(Sheet *sheet, const Location at); bool shadowed(Sheet *sheet, const Location at); -bool isbold(Sheet *sheet, const Location at); -bool underlined(Sheet *sheet, const Location at); -ColorNum getcolor(Sheet *sheet, const Location at, ColorAspect aspect); bool transparent(Sheet *sheet, const Location at); -FloatFormat getfltformat(Sheet *sheet, const Location at); PrecisionLevel getprecision(Sheet *sheet, const Location at); bool overridestyle(Sheet *sheet, const Location at, Style sty); bool setadjust(Sheet *sheet, const Location at, Adjust adjust); bool shadow(Sheet *sheet, const Location at, bool yep); -bool bold(Sheet *sheet, const Location at, bool yep); +bool makedim(Sheet *sheet, const Location at, bool yep); +bool embolden(Sheet *sheet, const Location at, bool yep); +bool italicize(Sheet *sheet, const Location at, bool yep); bool underline(Sheet *sheet, const Location at, bool yep); bool setcolor(Sheet *sheet, const Location at, ColorAspect asp, ColorNum col); bool lockcell(Sheet *sheet, const Location at, bool yep); diff --git a/src/common/style.c b/src/common/style.c index dbf96cc..74f3c17 100644 --- a/src/common/style.c +++ b/src/common/style.c @@ -32,8 +32,12 @@ void clearstyle(Style* s) { s->shadowed_set = false; s->transparent = false; s->transparent_set = false; + s->dim = false; + s->dim_set = false; s->bold = false; s->bold_set = false; + s->italic = false; + s->italic_set = false; s->underline = false; s->underline_set = false; } @@ -49,8 +53,12 @@ bool style_equal(Style l, Style r) { if (l.shadowed_set && (l.shadowed != r.shadowed)) return false; if (l.transparent_set != r.transparent_set) return false; if (l.transparent_set && (l.transparent != r.transparent)) return false; + if (l.dim_set != r.dim_set) return false; + if (l.dim_set && (l.dim != r.dim)) return false; if (l.bold_set != r.bold_set) return false; if (l.bold_set && (l.bold != r.bold)) return false; + if (l.italic_set != r.italic_set) return false; + if (l.italic_set && (l.italic != r.italic)) return false; if (l.underline_set != r.underline_set) return false; if (l.underline_set && (l.underline != r.underline)) return false; return true; diff --git a/src/common/style.h b/src/common/style.h index e5bb8c4..6dc5dc5 100644 --- a/src/common/style.h +++ b/src/common/style.h @@ -46,8 +46,12 @@ typedef struct unsigned int shadowed_set:1; unsigned int transparent:1; unsigned int transparent_set:1; + unsigned int dim:1; + unsigned int dim_set:1; unsigned int bold:1; unsigned int bold_set:1; + unsigned int italic:1; + unsigned int italic_set:1; unsigned int underline:1; unsigned int underline_set:1; } Style; diff --git a/src/common/token.c b/src/common/token.c index 497461c..15a930c 100644 --- a/src/common/token.c +++ b/src/common/token.c @@ -347,7 +347,9 @@ static size_t ptokatprec(char *dest, size_t size, size_t field_width, if (tok->u.style.fform != FLT_NO_FORMAT) ++nfields; if (tok->u.style.shadowed_set) ++nfields; if (tok->u.style.transparent_set) ++nfields; + if (tok->u.style.dim_set) ++nfields; if (tok->u.style.bold_set) ++nfields; + if (tok->u.style.italic_set) ++nfields; if (tok->u.style.underline_set) ++nfields; if (nfields == 0) cur += print_chars(dest, size, emptyrep); else { @@ -402,6 +404,14 @@ static size_t ptokatprec(char *dest, size_t size, size_t field_width, if (cur < size) dest[cur++] = ')'; ++shownfields; } + if (tok->u.style.dim_set) { + if (shownfields > 0 && cur < size) dest[cur++] = ','; + cur += print_chars(dest+cur, size-cur-1, "dim("); + cur += print_chars(dest+cur, size-cur-1, + (tok->u.style.dim) ? "" : "false"); + if (cur < size) dest[cur++] = ')'; + ++shownfields; + } if (tok->u.style.bold_set) { if (shownfields > 0 && cur < size) dest[cur++] = ','; cur += print_chars(dest+cur, size-cur-1, "bold("); @@ -410,6 +420,14 @@ static size_t ptokatprec(char *dest, size_t size, size_t field_width, if (cur < size) dest[cur++] = ')'; ++shownfields; } + if (tok->u.style.italic_set) { + if (shownfields > 0 && cur < size) dest[cur++] = ','; + cur += print_chars(dest+cur, size-cur-1, "italic("); + cur += print_chars(dest+cur, size-cur-1, + (tok->u.style.italic) ? "" : "false"); + if (cur < size) dest[cur++] = ')'; + ++shownfields; + } if (tok->u.style.underline_set) { if (shownfields > 0 && cur < size) dest[cur++] = ','; cur += print_chars(dest+cur, size-cur-1, "underline("); diff --git a/src/display.c b/src/display.c index 17757f4..fc5f054 100644 --- a/src/display.c +++ b/src/display.c @@ -111,15 +111,16 @@ static int do_attribute(Sheet *cursheet) case 2: { const char *typemenu[] = - { _("bB)old"), _("uU)nderline"), + { _("bB)old"), _("dD)im"), _("uU)nderline"), _("fF)oreground"), _("kBack)ground"), NULL }; switch (c = line_menu(prompt, typemenu, 0)) { case -2: case -1: c = K_INVALID; break; case 0: c = ADJUST_BOLD; break; - case 1: c = ADJUST_UNDERLINE; break; - case 2: c = ADJUST_FOREGROUND; break; - case 3: c = ADJUST_BACKGROUND; break; + case 1: c = ADJUST_DIM; break; + case 2: c = ADJUST_UNDERLINE; break; + case 3: c = ADJUST_FOREGROUND; break; + case 4: c = ADJUST_BACKGROUND; break; default: assert(0); } break; @@ -516,14 +517,15 @@ void redraw_sheet(Sheet *sheet) Style sc = getstyle(sheet, tmp); if ((size = cellwidth(sheet, tmp))) { - bool invert; - if (bufsz < (size*UTF8SZ+1)) buf = realloc(buf, bufsz=(size*UTF8SZ+1)); - printvalue(buf, (size*UTF8SZ + 1), size, quote, sc.fform, - sc.precision, sheet, tmp); + size_t esize = size; char* ebuf = buf; + if (sc.italic) { esize -= 2; *buf = '*'; ebuf += 1; } + size_t spot = printvalue(ebuf, (esize*UTF8SZ + 1), esize, quote, + sc.fform, sc.precision, sheet, tmp); + if (sc.italic) { ebuf[spot++] = '*'; ebuf[spot] = '\0'; } adjust(sc.adjust, buf, size); - assert(size>=cutoff); + assert(size >= cutoff); if (width + size - cutoff >= (size_t)(sheet->maxx)) { *(buf + cutoff + (size_t)sheet->maxx - width) = '\0'; @@ -544,14 +546,15 @@ void redraw_sheet(Sheet *sheet) } if (usecp == curcp) init_pair(curcp++, fg, bg); wcolor_set(stdscr, usecp, NULL); - invert = + bool invert = (ms != UNMARKED) && loc_in_box(tmp, sheet->mark1, sheet->mark2); if (x == sheet->cur[X] && (y - (header ? 1 : 0) + sheet->offy == sheet->cur[Y])) invert = (ms == MARKING) ? true : !invert; if (invert) (void)wattron(stdscr,DEF_CELLCURSOR); - if (sc.bold) wattron(stdscr,A_BOLD); - if (sc.underline) wattron(stdscr,A_UNDERLINE); + if (sc.dim) wattron(stdscr, A_DIM); + if (sc.bold) wattron(stdscr, A_BOLD); + if (sc.underline) wattron(stdscr, A_UNDERLINE); (void)mvwaddstr(stdscr, y+(int)(sheet->oriy), (int)(sheet->orix + width), buf+cutoff); diff --git a/src/fteapot.fl b/src/fteapot.fl index c19f954..3a6bbd3 100644 --- a/src/fteapot.fl +++ b/src/fteapot.fl @@ -160,8 +160,12 @@ class TeapotTable {open : {public Fl_Table}} ColorNum fgcn = sc.aspect[FOREGROUND]; if (fgcn == NO_COLOR_SET) fgcn = DefaultCN[FOREGROUND]; Fl_Color cellfg = ((Fl_Color *)(cursheet->palette))[fgcn]; + if (sc.dim) cellfg = fl_color_average(cellfg, cellbg, 0.6f); fl_color(cellfg); - fl_font(FL_HELVETICA | (sc.bold ? FL_BOLD : 0), 14); + Fl_Font cellfont = FL_HELVETICA; + if (sc.bold) cellfont |= FL_BOLD; + if (sc.italic) cellfont |= FL_ITALIC; + fl_font(cellfont, 14); size_t len = printvalue(s, sizeof(s), 0, quote, sc.fform, sc.precision, cursheet, test); @@ -542,12 +546,24 @@ class MainWindow {open} user_data ADJUST_LABEL xywh {0 0 36 21} shortcut 0x80061 divider } + MenuItem dim { + label {&Dim} + user_data ADJUST_DIM + protected xywh {0 0 34 21} + code0 {o->flags |= FL_MENU_TOGGLE;} + } MenuItem bold { label {&Bold} user_data ADJUST_BOLD protected xywh {0 0 34 21} shortcut 0x80062 code0 {o->flags |= FL_MENU_TOGGLE;} } + MenuItem italic { + label {&Italic} + user_data ADJUST_ITALIC + protected xywh {0 0 34 21} + code0 {o->flags |= FL_MENU_TOGGLE;} + } MenuItem underline { label {&Underline} user_data ADJUST_UNDERLINE @@ -737,8 +753,9 @@ class MainWindow {open} else lock->clear(); if (ignored(cell)) ignore->set(); else ignore->clear(); - if (sc.bold) bold->set(); - else bold->clear(); + if (sc.dim) dim->set(); else dim->clear(); + if (sc.bold) bold->set(); else bold->clear(); + if (sc.italic) italic->set(); else italic->clear(); if (sc.underline) underline->set(); else underline->clear(); switch (sc.fform) {