@trebco/treb 29.4.1 → 29.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -30,12 +30,12 @@ import type { ParseResult } from 'treb-parser';
30
30
  import { Parser } from 'treb-parser';
31
31
  import type { RangeType, AddressType, HyperlinkType } from './address-type';
32
32
  import { is_range, ShiftRange, InRange, is_address } from './address-type';
33
- import type { ImportedSheetData, AnchoredAnnotation, CellParseResult, AnnotationLayout, Corner as LayoutCorner, IArea, GradientStop, Color } from 'treb-base-types';
33
+ import type { ImportedSheetData, AnchoredAnnotation, CellParseResult, AnnotationLayout, Corner as LayoutCorner, IArea, GradientStop, Color, HTMLColor, ThemeColor } from 'treb-base-types';
34
34
  import type { SerializedValueType } from 'treb-base-types';
35
35
  import type { Sheet} from './workbook-sheet2';
36
36
  import { VisibleState } from './workbook-sheet2';
37
37
  import type { CellAnchor } from './drawing2/drawing2';
38
- import { XMLUtils } from './xml-utils';
38
+ import { type DOMContent, XMLUtils } from './xml-utils';
39
39
 
40
40
  // import { one_hundred_pixels } from './constants';
41
41
  import { ColumnWidthToPixels } from './column-width';
@@ -84,7 +84,7 @@ export class Importer {
84
84
  };
85
85
  v?: string|number|{
86
86
  t$: string;
87
- a$?: any;
87
+ a$?: DOMContent;
88
88
  };
89
89
  f?: string|{
90
90
  t$: string;
@@ -447,12 +447,12 @@ export class Importer {
447
447
 
448
448
  const color_element = rule.colorScale.color[index];
449
449
  if (color_element.a$.rgb) {
450
- color.text = '#' + color_element.a$.rgb.substring(2);
450
+ (color as HTMLColor).text = '#' + color_element.a$.rgb.substring(2);
451
451
  }
452
452
  else if (color_element.a$.theme) {
453
- color.theme = Number(color_element.a$.theme) || 0;
453
+ (color as ThemeColor).theme = Number(color_element.a$.theme) || 0;
454
454
  if (color_element.a$.tint) {
455
- color.tint = Math.round(color_element.a$.tint * 1000) / 1000;
455
+ (color as ThemeColor).tint = Math.round(color_element.a$.tint * 1000) / 1000;
456
456
  }
457
457
  }
458
458
 
@@ -762,15 +762,6 @@ export class Importer {
762
762
  row_heights[row_index - 1] = height;
763
763
  }
764
764
 
765
- /*
766
- if (row.a$?.ht && row.a$?.customHeight) {
767
- const num = Number(row.a$.ht);
768
- if (!isNaN(num)) {
769
- row_heights[row_index - 1] = Math.round(num * 4 / 3); // seems to be the excel unit -> pixel ratio
770
- }
771
- }
772
- */
773
-
774
765
  let cells = row.c || [];
775
766
  if (!Array.isArray(cells)) { cells = [cells]; }
776
767
 
@@ -22,7 +22,7 @@
22
22
  // import * as ElementTree from 'elementtree';
23
23
  // import { Element, ElementTree as Tree } from 'elementtree';
24
24
 
25
- import { type CompositeBorderEdge, Style, type CellStyle, type PropertyKeys, type Color } from 'treb-base-types';
25
+ import { type CompositeBorderEdge, Style, type CellStyle, type PropertyKeys, type Color, IsHTMLColor, IsThemeColor, type ThemeColor, type HTMLColor, ThemeColorIndex } from 'treb-base-types';
26
26
  import { Theme } from './workbook-theme2';
27
27
  import { NumberFormatCache } from 'treb-format';
28
28
  import { XMLUtils } from './xml-utils';
@@ -85,12 +85,14 @@ export interface CellXf {
85
85
 
86
86
  }
87
87
 
88
+ /*
88
89
  interface ColorAttributes {
89
90
  indexed?: string;
90
91
  rgb?: string;
91
92
  theme?: string;
92
93
  tint?: string;
93
94
  }
95
+ */
94
96
 
95
97
  export interface BorderEdge {
96
98
  style?: string;
@@ -303,11 +305,11 @@ export class StyleCache {
303
305
  //}
304
306
 
305
307
  if (composite.text) {
306
- if (composite.text.text) {
308
+ if (IsHTMLColor(composite.text)) {
307
309
  font.color_argb = composite.text.text;
308
310
  }
309
- else if (typeof composite.text.theme === 'number') {
310
- font.color_theme = composite.text.theme;
311
+ else if (IsThemeColor(composite.text)) {
312
+ font.color_theme = ThemeColorIndex(composite.text);
311
313
  if (composite.text.tint) {
312
314
  font.color_tint = composite.text.tint;
313
315
  }
@@ -317,11 +319,11 @@ export class StyleCache {
317
319
  const TranslateBorder = (src: CompositeBorderEdge, dest: BorderEdge) => {
318
320
  if (src.width) {
319
321
  dest.style = 'thin';
320
- if (src.color.text) {
322
+ if (IsHTMLColor(src.color)) {
321
323
  dest.rgba =src.color.text;
322
324
  }
323
- else if (typeof src.color.theme === 'number') {
324
- dest.theme = src.color.theme;
325
+ else if (IsThemeColor(src.color)) {
326
+ dest.theme = ThemeColorIndex(src.color);
325
327
  if (src.color.tint) {
326
328
  dest.tint = src.color.tint;
327
329
  }
@@ -440,12 +442,12 @@ export class StyleCache {
440
442
 
441
443
  if (composite.fill) {
442
444
  fill.pattern_type = 'solid';
443
- if (composite.fill.text) {
445
+ if (IsHTMLColor(composite.fill)) {
444
446
  fill.fg_color = { argb: composite.fill.text };
445
447
  options.fill = fill;
446
448
  }
447
- else if (typeof composite.fill.theme === 'number') {
448
- fill.fg_color = { theme: composite.fill.theme };
449
+ else if (IsThemeColor(composite.fill)) {
450
+ fill.fg_color = { theme: ThemeColorIndex(composite.fill) };
449
451
  if (composite.fill.tint) {
450
452
  fill.fg_color.tint = composite.fill.tint;
451
453
  }
@@ -619,7 +621,7 @@ export class StyleCache {
619
621
  };
620
622
 
621
623
  if (fill.fg_color.tint) {
622
- props.fill.tint = Math.round(fill.fg_color.tint * 1000) / 1000;
624
+ (props.fill as ThemeColor).tint = Math.round(fill.fg_color.tint * 1000) / 1000;
623
625
  }
624
626
 
625
627
  /*
@@ -1317,12 +1319,12 @@ export class StyleCache {
1317
1319
  const ParseDXFColor = (element: any) => {
1318
1320
  const color: Color = {};
1319
1321
  if (element.a$.rgb) {
1320
- color.text = '#' + element.a$.rgb.substring(2);
1322
+ (color as HTMLColor).text = '#' + element.a$.rgb.substring(2);
1321
1323
  }
1322
1324
  else if (element.a$.theme) {
1323
- color.theme = Number(element.a$.theme) || 0;
1325
+ (color as ThemeColor).theme = Number(element.a$.theme) || 0;
1324
1326
  if (element.a$.tint) {
1325
- color.tint = Math.round(element.a$.tint * 1000) / 1000;
1327
+ (color as ThemeColor).tint = Math.round(element.a$.tint * 1000) / 1000;
1326
1328
  }
1327
1329
  }
1328
1330
  return color;
@@ -28,33 +28,17 @@ const xmlparser2 = new XMLParser(XMLOptions2);
28
28
 
29
29
  // import * as he from 'he';
30
30
 
31
- //import { Drawing, TwoCellAnchor, CellAnchor } from './drawing/drawing';
32
31
  import type { TwoCellAnchor, CellAnchor } from './drawing2/drawing2';
33
32
 
34
- // import { ImportedSheetData, IArea } from 'treb-base-types/src';
35
33
  import { SharedStrings } from './shared-strings2';
36
34
  import { StyleCache } from './workbook-style2';
37
35
  import { Theme } from './workbook-theme2';
38
36
  import { Sheet, VisibleState } from './workbook-sheet2';
39
37
  import type { RelationshipMap } from './relationship';
40
38
  import { ZipWrapper } from './zip-wrapper';
41
- import type { CellStyle } from 'treb-base-types';
39
+ import type { CellStyle, ThemeColor } from 'treb-base-types';
42
40
  import type { SerializedNamed } from 'treb-data-model';
43
41
 
44
-
45
- /*
46
- const XMLTypeMap = {
47
- 'sheet': 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml',
48
- 'theme': 'application/vnd.openxmlformats-officedocument.theme+xml',
49
- 'drawing': 'application/vnd.openxmlformats-officedocument.drawing+xml',
50
- 'chart': 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml',
51
- 'themeOverride': 'application/vnd.openxmlformats-officedocument.themeOverride+xml',
52
- 'ctrlProp': 'application/vnd.ms-excel.controlproperties+xml',
53
- 'style': 'application/vnd.ms-office.chartstyle+xml',
54
- 'colors': 'application/vnd.ms-office.chartcolorstyle+xml',
55
- };
56
- */
57
-
58
42
  export const ConditionalFormatOperators: Record<string, string> = {
59
43
  greaterThan: '>',
60
44
  greaterThanOrEquals: '>=',
@@ -413,7 +397,7 @@ export class Workbook {
413
397
  if (fill['a:schemeClr']['a:lumOff']?.a$?.val) {
414
398
  const num = Number(fill['a:schemeClr']['a:lumOff'].a$.val);
415
399
  if (!isNaN(num)) {
416
- style.fill.tint = num / 1e5;
400
+ (style.fill as ThemeColor).tint = num / 1e5;
417
401
  }
418
402
  }
419
403
  }
@@ -20,14 +20,62 @@
20
20
  */
21
21
 
22
22
  import { Unescape } from './unescape_xml';
23
- import type { X2jOptions } from 'fast-xml-parser';
23
+ import { type X2jOptions, XMLBuilder, type XmlBuilderOptions } from 'fast-xml-parser';
24
24
 
25
25
  export const XMLTagProcessor = (name: string, value: string): string => Unescape(value);
26
26
 
27
27
  export interface DOMContent {
28
- [index: string]: string|DOMContent|string[]|DOMContent[]|number|number[];
28
+ [index: string]: string|DOMContent|string[]|DOMContent[]|number|number[]|undefined;
29
29
  }
30
30
 
31
+ /**
32
+ * not sure why we have to do this, but filter attributes that
33
+ * have value === undefined
34
+ */
35
+ export const ScrubXML = (dom: DOMContent) => {
36
+ if (dom) {
37
+ if (Array.isArray(dom)) {
38
+ for (const entry of dom) {
39
+ ScrubXML(entry);
40
+ }
41
+ }
42
+ else if (typeof dom === 'object') {
43
+ for (const [key, value] of Object.entries(dom)) {
44
+ if (key === 'a$') {
45
+ if (typeof value === 'object') {
46
+ const replacement: DOMContent = {};
47
+ for (const [attr_name, attr_value] of Object.entries(value)) {
48
+ if (attr_value !== undefined) {
49
+ replacement[attr_name] = attr_value;
50
+ }
51
+ }
52
+ dom[key] = replacement;
53
+ }
54
+ }
55
+ else {
56
+ ScrubXML(value as DOMContent);
57
+ }
58
+ }
59
+ }
60
+ }
61
+ return dom;
62
+ };
63
+
64
+ export const PatchXMLBuilder = (options: Partial<XmlBuilderOptions>) => {
65
+
66
+ const builder = new XMLBuilder(options);
67
+ const build = builder.build;
68
+
69
+ builder.build = (arg: DOMContent) => {
70
+ return build.call(builder, ScrubXML(arg)); // get the "this" value right
71
+ }
72
+
73
+ return builder;
74
+
75
+ };
76
+
77
+ //////////////////
78
+
31
79
  export const XMLOptions: Partial<X2jOptions> = {
32
80
  ignoreAttributes: false,
33
81
  attributeNamePrefix: '__',
@@ -58,7 +58,7 @@ export class ZipWrapper {
58
58
  public Set(path: string, text: string) {
59
59
 
60
60
  this.text.set(path, text);
61
- if (!!this.records[path]) {
61
+ if (this.records[path]) {
62
62
  delete this.records[path];
63
63
  }
64
64
  }
@@ -20,7 +20,7 @@
20
20
  */
21
21
 
22
22
  import { Editor, type NodeDescriptor } from './editor';
23
- import { Area, Cell, type CellStyle, type CellValue, Rectangle, Style, type Theme, ThemeColor2 } from 'treb-base-types';
23
+ import { Area, Cell, type CellStyle, type CellValue, Rectangle, Style, type Theme, ResolveThemeColor } from 'treb-base-types';
24
24
  import { DataModel, type ViewModel, type GridSelection } from 'treb-data-model';
25
25
  import { Autocomplete } from './autocomplete';
26
26
  import { UA } from '../util/ua';
@@ -287,8 +287,8 @@ export class OverlayEditor extends Editor<ResetSelectionEvent> {
287
287
  const style: CellStyle = cell.style || {};
288
288
 
289
289
  this.edit_node.style.font = Style.Font(style, this.scale);
290
- this.edit_node.style.color = ThemeColor2(this.theme, style.text, 1);
291
- this.edit_inset.style.backgroundColor = ThemeColor2(this.theme, style.fill, 0);
290
+ this.edit_node.style.color = ResolveThemeColor(this.theme, style.text, 1);
291
+ this.edit_inset.style.backgroundColor = ResolveThemeColor(this.theme, style.fill, 0);
292
292
 
293
293
  // NOTE: now that we dropped support for IE11, we can probably
294
294
  // remove more than one class at the same time.
@@ -24,7 +24,7 @@ import type { DataModel, ViewModel, Annotation } from 'treb-data-model';
24
24
 
25
25
  import type { Tile } from '../types/tile';
26
26
  import type { Theme, Point, Extent, Size, Position, ICellAddress, Table, IArea } from 'treb-base-types';
27
- import { Style, Area, Rectangle, ThemeColor } from 'treb-base-types';
27
+ import { Style, Area, Rectangle, ResolveThemeColor } from 'treb-base-types';
28
28
 
29
29
  import { MouseDrag } from '../types/drag_mask';
30
30
  import type { GridEvent } from '../types/grid_events';
@@ -1279,7 +1279,7 @@ export abstract class BaseLayout {
1279
1279
  this.row_header.style.backgroundColor =
1280
1280
  this.column_header.style.backgroundColor =
1281
1281
  this.corner.style.backgroundColor =
1282
- theme.headers?.fill ? ThemeColor(theme, theme.headers.fill) : '';
1282
+ theme.headers?.fill ? ResolveThemeColor(theme, theme.headers.fill, 0) : '';
1283
1283
 
1284
1284
  // theme.headers?.background || '';
1285
1285
  // theme.header_background_color || ''; // this.theme.header_background;
@@ -1291,7 +1291,7 @@ export abstract class BaseLayout {
1291
1291
 
1292
1292
  for (const row of this.grid_tiles) {
1293
1293
  for (const tile of row) {
1294
- tile.style.backgroundColor = ThemeColor(theme, theme.grid_cell?.fill) || '#fff';
1294
+ tile.style.backgroundColor = ResolveThemeColor(theme, theme.grid_cell?.fill, 0) || '#fff';
1295
1295
  }
1296
1296
  }
1297
1297
 
@@ -25,7 +25,7 @@ import type { ICellAddress,
25
25
  CellStyle,
26
26
  Theme,
27
27
  HorizontalAlign} from 'treb-base-types';
28
- import { TextPartFlag, Style, ValueType, Area, Rectangle, ThemeColor, ThemeColor2 } from 'treb-base-types';
28
+ import { TextPartFlag, Style, ValueType, Area, Rectangle, ResolveThemeColor, IsDefinedColor } from 'treb-base-types';
29
29
 
30
30
  import type { Tile } from '../types/tile';
31
31
  import { FontMetricsCache as FontMetricsCache2 } from '../util/fontmetrics2';
@@ -307,7 +307,7 @@ export class TileRenderer {
307
307
  }
308
308
 
309
309
  context.setTransform(scale, 0, 0, scale, 0, 0);
310
- context.fillStyle = this.theme.headers?.fill ? ThemeColor2(this.theme, this.theme.headers.fill) : '';
310
+ context.fillStyle = this.theme.headers?.fill ? ResolveThemeColor(this.theme, this.theme.headers.fill) : '';
311
311
 
312
312
  context.fillRect(0, 0, x, header_size.y);
313
313
  context.fillRect(0, 0, header_size.x, y);
@@ -354,7 +354,7 @@ export class TileRenderer {
354
354
  context.textBaseline = 'middle';
355
355
  context.font = Style.Font(this.theme.headers||{}, this.layout.scale);
356
356
 
357
- context.fillStyle = ThemeColor2(this.theme, this.theme.headers?.text);
357
+ context.fillStyle = ResolveThemeColor(this.theme, this.theme.headers?.text);
358
358
 
359
359
  if (this.view.active_sheet.freeze.rows && this.layout.header_offset.x > 1) {
360
360
 
@@ -407,7 +407,7 @@ export class TileRenderer {
407
407
  return;
408
408
  }
409
409
 
410
- context.fillStyle = ThemeColor2(this.theme, this.theme.headers?.text, 0);
410
+ context.fillStyle = ResolveThemeColor(this.theme, this.theme.headers?.text, 0);
411
411
 
412
412
  context.beginPath();
413
413
 
@@ -434,7 +434,7 @@ export class TileRenderer {
434
434
  return;
435
435
  }
436
436
 
437
- context.fillStyle = ThemeColor2(this.theme, this.theme.headers?.text, 0);
437
+ context.fillStyle = ResolveThemeColor(this.theme, this.theme.headers?.text, 0);
438
438
 
439
439
  context.beginPath();
440
440
 
@@ -473,7 +473,7 @@ export class TileRenderer {
473
473
  context.textBaseline = 'middle';
474
474
  context.font = Style.Font(this.theme.headers||{}, this.layout.scale);
475
475
 
476
- context.fillStyle = this.theme.headers?.fill ? ThemeColor2(this.theme, this.theme.headers.fill) : '';
476
+ context.fillStyle = this.theme.headers?.fill ? ResolveThemeColor(this.theme, this.theme.headers.fill) : '';
477
477
  context.fillRect(0, 0, tile.logical_size.width, this.layout.header_offset.y);
478
478
 
479
479
  // context.strokeStyle = this.theme.grid_color || '';
@@ -507,7 +507,7 @@ export class TileRenderer {
507
507
 
508
508
  const context = tile.getContext('2d', { alpha: false });
509
509
  if (!context) continue;
510
- context.fillStyle = this.theme.headers?.fill ? ThemeColor2(this.theme, this.theme.headers.fill) : '';
510
+ context.fillStyle = this.theme.headers?.fill ? ResolveThemeColor(this.theme, this.theme.headers.fill) : '';
511
511
 
512
512
  context.setTransform(scale, 0, 0, scale, 0, 0);
513
513
 
@@ -1065,7 +1065,7 @@ export class TileRenderer {
1065
1065
  protected ResolveColors(style: CellStyle): CellStyle {
1066
1066
 
1067
1067
  const resolved = {...style};
1068
- resolved.text = { text: ThemeColor2(this.theme, style.text, 1) };
1068
+ resolved.text = { text: ResolveThemeColor(this.theme, style.text, 1) };
1069
1069
 
1070
1070
  // TODO: other colors
1071
1071
 
@@ -1126,7 +1126,7 @@ export class TileRenderer {
1126
1126
 
1127
1127
  // paint top background
1128
1128
 
1129
- let color = ThemeColor2(this.theme, numpad[8].fill);
1129
+ let color = ResolveThemeColor(this.theme, numpad[8].fill);
1130
1130
  if (color) {
1131
1131
  context.fillStyle = color
1132
1132
  context.fillRect(left + 0, top - 1, width, 1);
@@ -1134,7 +1134,7 @@ export class TileRenderer {
1134
1134
 
1135
1135
  // paint left background
1136
1136
 
1137
- color = ThemeColor2(this.theme, numpad[4].fill);
1137
+ color = ResolveThemeColor(this.theme, numpad[4].fill);
1138
1138
  if (color) {
1139
1139
  context.fillStyle = color
1140
1140
  context.fillRect(left - 1, top, 1, height);
@@ -1142,7 +1142,7 @@ export class TileRenderer {
1142
1142
 
1143
1143
  // paint our background. note this one goes up, left
1144
1144
 
1145
- color = ThemeColor2(this.theme, style.fill);
1145
+ color = ResolveThemeColor(this.theme, style.fill);
1146
1146
  if (color) {
1147
1147
  context.fillStyle = color;
1148
1148
  context.fillRect(left - 1, top - 1, width + 1, height + 1);
@@ -1150,7 +1150,7 @@ export class TileRenderer {
1150
1150
 
1151
1151
  // fill of cell to the right
1152
1152
 
1153
- color = ThemeColor2(this.theme, numpad[6].fill);
1153
+ color = ResolveThemeColor(this.theme, numpad[6].fill);
1154
1154
  if (color) {
1155
1155
  context.fillStyle = color;
1156
1156
  context.fillRect(left + width - 1, top - 1, 1, height + 1);
@@ -1159,7 +1159,7 @@ export class TileRenderer {
1159
1159
 
1160
1160
  // fill of cell underneath
1161
1161
 
1162
- color = ThemeColor2(this.theme, numpad[2].fill);
1162
+ color = ResolveThemeColor(this.theme, numpad[2].fill);
1163
1163
  if (color) {
1164
1164
  context.fillStyle = color;
1165
1165
  context.fillRect(left - 1, top + height - 1, width + 1, 1);
@@ -1168,54 +1168,54 @@ export class TileRenderer {
1168
1168
  // --- corner borders ------------------------------------------------------
1169
1169
 
1170
1170
  if (numpad[6].border_top && !numpad[6].border_left) {
1171
- context.fillStyle = ThemeColor2(this.theme, numpad[6].border_top_fill, 1);
1171
+ context.fillStyle = ResolveThemeColor(this.theme, numpad[6].border_top_fill, 1);
1172
1172
  context.fillRect(left + width - 1, top - 2 + numpad[6].border_top, 1, 1);
1173
1173
  }
1174
1174
  if (numpad[9].border_left) {
1175
- context.fillStyle = ThemeColor2(this.theme, numpad[9].border_left_fill, 1);
1175
+ context.fillStyle = ResolveThemeColor(this.theme, numpad[9].border_left_fill, 1);
1176
1176
  context.fillRect(left + width - 1, top - 1, 1, 1);
1177
1177
  }
1178
1178
  if (numpad[9].border_bottom) {
1179
- context.fillStyle = ThemeColor2(this.theme, numpad[9].border_bottom_fill, 1);
1179
+ context.fillStyle = ResolveThemeColor(this.theme, numpad[9].border_bottom_fill, 1);
1180
1180
  context.fillRect(left + width - 1, top - 2 + numpad[9].border_bottom, 1, 1);
1181
1181
  }
1182
1182
 
1183
1183
  if (numpad[4].border_top && !numpad[4].border_right) {
1184
- context.fillStyle = ThemeColor2(this.theme, numpad[4].border_right_fill, 1);
1184
+ context.fillStyle = ResolveThemeColor(this.theme, numpad[4].border_right_fill, 1);
1185
1185
  context.fillRect(left - 1, top - 2 + numpad[4].border_top, 1, 1);
1186
1186
  }
1187
1187
  if (numpad[7].border_right) {
1188
- context.fillStyle = ThemeColor2(this.theme, numpad[7].border_right_fill, 1);
1188
+ context.fillStyle = ResolveThemeColor(this.theme, numpad[7].border_right_fill, 1);
1189
1189
  context.fillRect(left - 1, top - 1, 1, 1);
1190
1190
  }
1191
1191
  if (numpad[7].border_bottom) {
1192
- context.fillStyle = ThemeColor2(this.theme, numpad[7].border_bottom_fill, 1);
1192
+ context.fillStyle = ResolveThemeColor(this.theme, numpad[7].border_bottom_fill, 1);
1193
1193
  context.fillRect(left - 1, top - 2 + numpad[7].border_bottom, 1, 1);
1194
1194
  }
1195
1195
 
1196
1196
  if (numpad[6].border_bottom && !numpad[6].border_left) {
1197
- context.fillStyle = ThemeColor2(this.theme, numpad[6].border_bottom_fill, 1);
1197
+ context.fillStyle = ResolveThemeColor(this.theme, numpad[6].border_bottom_fill, 1);
1198
1198
  context.fillRect(left + width - 1, top + height - numpad[6].border_bottom, 1, 1);
1199
1199
  }
1200
1200
  if (numpad[3].border_left) {
1201
- context.fillStyle = ThemeColor2(this.theme, numpad[3].border_left_fill, 1);
1201
+ context.fillStyle = ResolveThemeColor(this.theme, numpad[3].border_left_fill, 1);
1202
1202
  context.fillRect(left + width - 1, top + height - 1, 1, 1);
1203
1203
  }
1204
1204
  if (numpad[3].border_top) {
1205
- context.fillStyle = ThemeColor2(this.theme, numpad[3].border_top_fill, 1);
1205
+ context.fillStyle = ResolveThemeColor(this.theme, numpad[3].border_top_fill, 1);
1206
1206
  context.fillRect(left + width - 1, top + height - numpad[3].border_top, 1, 1);
1207
1207
  }
1208
1208
 
1209
1209
  if (numpad[4].border_bottom && !numpad[4].border_right) {
1210
- context.fillStyle = ThemeColor2(this.theme, numpad[4].border_bottom_fill, 1);
1210
+ context.fillStyle = ResolveThemeColor(this.theme, numpad[4].border_bottom_fill, 1);
1211
1211
  context.fillRect(left - 1, top + height - numpad[4].border_bottom, 1, 1);
1212
1212
  }
1213
1213
  if (numpad[1].border_right) {
1214
- context.fillStyle = ThemeColor2(this.theme, numpad[1].border_right_fill, 1);
1214
+ context.fillStyle = ResolveThemeColor(this.theme, numpad[1].border_right_fill, 1);
1215
1215
  context.fillRect(left - 1, top + height - 1, 1, 1);
1216
1216
  }
1217
1217
  if (numpad[1].border_top) {
1218
- context.fillStyle = ThemeColor2(this.theme, numpad[1].border_top_fill, 1);
1218
+ context.fillStyle = ResolveThemeColor(this.theme, numpad[1].border_top_fill, 1);
1219
1219
  context.fillRect(left - 1, top + height - numpad[1].border_top, 1, 1);
1220
1220
  }
1221
1221
 
@@ -1224,12 +1224,12 @@ export class TileRenderer {
1224
1224
  // paint top border
1225
1225
 
1226
1226
  if (numpad[8].border_bottom) {
1227
- context.fillStyle = ThemeColor2(this.theme, numpad[8].border_bottom_fill, 1);
1227
+ context.fillStyle = ResolveThemeColor(this.theme, numpad[8].border_bottom_fill, 1);
1228
1228
  if (numpad[8].border_bottom === 2) {
1229
1229
  context.fillRect(left - 1, top - 2, width + 1, 1);
1230
1230
  context.fillRect(left - 1, top - 0, width + 1, 1);
1231
- context.fillStyle = ThemeColor2(this.theme, numpad[8].fill)
1232
- || ThemeColor(this.theme, this.theme.grid_cell?.fill) || '#fff';
1231
+ context.fillStyle = ResolveThemeColor(this.theme, numpad[8].fill)
1232
+ || ResolveThemeColor(this.theme, this.theme.grid_cell?.fill, 0) || '#fff';
1233
1233
  context.fillRect(left - 1, top - 1, width + 1, 1);
1234
1234
  }
1235
1235
  else {
@@ -1240,26 +1240,26 @@ export class TileRenderer {
1240
1240
  // paint left border
1241
1241
 
1242
1242
  if (numpad[4].border_right) {
1243
- context.fillStyle = ThemeColor2(this.theme, numpad[4].border_right_fill, 1);
1243
+ context.fillStyle = ResolveThemeColor(this.theme, numpad[4].border_right_fill, 1);
1244
1244
  context.fillRect(left - 1, top - 1, 1, height + 1);
1245
1245
  }
1246
1246
 
1247
1247
  // paint right border?
1248
1248
 
1249
1249
  if (numpad[6].border_left) {
1250
- context.fillStyle = ThemeColor2(this.theme, numpad[6].border_left_fill, 1);
1250
+ context.fillStyle = ResolveThemeColor(this.theme, numpad[6].border_left_fill, 1);
1251
1251
  context.fillRect(left + width - 1, top - 1, 1, height + 1);
1252
1252
  }
1253
1253
 
1254
1254
  // bottom? (...)
1255
1255
 
1256
1256
  if (numpad[2].border_top) {
1257
- context.fillStyle = ThemeColor2(this.theme, numpad[2].border_top_fill, 1);
1257
+ context.fillStyle = ResolveThemeColor(this.theme, numpad[2].border_top_fill, 1);
1258
1258
  if (numpad[2].border_top === 2) {
1259
1259
  context.fillRect(left - 1, top + height - 2, width + 1, 1);
1260
1260
  context.fillRect(left - 1, top + height - 0, width + 1, 1);
1261
- context.fillStyle = ThemeColor2(this.theme, numpad[2].fill)
1262
- || ThemeColor(this.theme, this.theme.grid_cell?.fill) || '#fff';
1261
+ context.fillStyle = ResolveThemeColor(this.theme, numpad[2].fill)
1262
+ || ResolveThemeColor(this.theme, this.theme.grid_cell?.fill, 0) || '#fff';
1263
1263
  context.fillRect(left - 1, top + height - 1, width + 1, 1);
1264
1264
  }
1265
1265
  else {
@@ -1270,12 +1270,12 @@ export class TileRenderer {
1270
1270
  // -- our borders ----------------------------------------------------------
1271
1271
 
1272
1272
  if (style.border_top) {
1273
- context.fillStyle = ThemeColor2(this.theme, style.border_top_fill, 1);
1273
+ context.fillStyle = ResolveThemeColor(this.theme, style.border_top_fill, 1);
1274
1274
  if (style.border_top === 2) {
1275
1275
  context.fillRect(left - 1, top - 2, width + 1, 1);
1276
1276
  context.fillRect(left - 1, top + 0, width + 1, 1);
1277
- context.fillStyle = ThemeColor2(this.theme, style.fill)
1278
- || ThemeColor(this.theme, this.theme.grid_cell?.fill) || '#fff';
1277
+ context.fillStyle = ResolveThemeColor(this.theme, style.fill)
1278
+ || ResolveThemeColor(this.theme, this.theme.grid_cell?.fill, 0) || '#fff';
1279
1279
  context.fillRect(left - 1, top - 1, width + 1, 1);
1280
1280
  }
1281
1281
  else {
@@ -1284,22 +1284,22 @@ export class TileRenderer {
1284
1284
  }
1285
1285
 
1286
1286
  if (style.border_left) {
1287
- context.fillStyle = ThemeColor2(this.theme, style.border_left_fill, 1);
1287
+ context.fillStyle = ResolveThemeColor(this.theme, style.border_left_fill, 1);
1288
1288
  context.fillRect(left - 1, top - 1, 1, height + 1);
1289
1289
  }
1290
1290
 
1291
1291
  if (style.border_right) {
1292
- context.fillStyle = ThemeColor2(this.theme, style.border_right_fill, 1);
1292
+ context.fillStyle = ResolveThemeColor(this.theme, style.border_right_fill, 1);
1293
1293
  context.fillRect(left + width - 1, top - 1, 1, height + 1);
1294
1294
  }
1295
1295
 
1296
1296
  if (style.border_bottom) {
1297
- context.fillStyle = ThemeColor2(this.theme, style.border_bottom_fill, 1);
1297
+ context.fillStyle = ResolveThemeColor(this.theme, style.border_bottom_fill, 1);
1298
1298
  if (style.border_bottom === 2) {
1299
1299
  context.fillRect(left - 1, top + height - 2, width + 1, 1);
1300
1300
  context.fillRect(left - 1, top + height + 0, width + 1, 1);
1301
- context.fillStyle = ThemeColor2(this.theme, style.fill)
1302
- || ThemeColor(this.theme, this.theme.grid_cell?.fill) || '#fff';
1301
+ context.fillStyle = ResolveThemeColor(this.theme, style.fill)
1302
+ || ResolveThemeColor(this.theme, this.theme.grid_cell?.fill, 0) || '#fff';
1303
1303
  context.fillRect(left - 1, top + height - 1, width + 1, 1);
1304
1304
  }
1305
1305
  else {
@@ -1412,14 +1412,14 @@ export class TileRenderer {
1412
1412
  }
1413
1413
  else {
1414
1414
 
1415
- const fill = ThemeColor2(this.theme, style.fill);
1415
+ const fill = ResolveThemeColor(this.theme, style.fill);
1416
1416
 
1417
1417
  if (fill) {
1418
1418
  context.fillStyle = fill;
1419
1419
  context.fillRect(0, 0, width - 1, height - 1);
1420
1420
  }
1421
1421
  else {
1422
- context.fillStyle = ThemeColor(this.theme, this.theme.grid_cell?.fill) || '#fff';
1422
+ context.fillStyle = ResolveThemeColor(this.theme, this.theme.grid_cell?.fill, 0) || '#fff';
1423
1423
  context.fillRect(0, 0, width - 1, height - 1);
1424
1424
  }
1425
1425
 
@@ -1578,7 +1578,7 @@ export class TileRenderer {
1578
1578
  width,
1579
1579
  height);
1580
1580
 
1581
- context.strokeStyle = context.fillStyle = ThemeColor2(this.theme, style.text, 1);
1581
+ context.strokeStyle = context.fillStyle = ResolveThemeColor(this.theme, style.text, 1);
1582
1582
 
1583
1583
  // there's an issue with theme colors, the function may not be able
1584
1584
  // to translate so we need to update the style (using a copy) to
@@ -1871,10 +1871,11 @@ export class TileRenderer {
1871
1871
  for (const element of overflow_backgrounds) {
1872
1872
 
1873
1873
  if ( element.cell.style?.fill &&
1874
- (element.cell.style.fill.text || element.cell.style.fill.theme || element.cell.style.fill.theme === 0) &&
1874
+ IsDefinedColor(element.cell.style.fill) &&
1875
+ // (element.cell.style.fill.text || element.cell.style.fill.theme || element.cell.style.fill.theme === 0) &&
1875
1876
  !this.options.grid_over_background) {
1876
1877
 
1877
- context.fillStyle = ThemeColor(this.theme, element.cell.style.fill);
1878
+ context.fillStyle = ResolveThemeColor(this.theme, element.cell.style.fill, 0);
1878
1879
  context.fillRect(element.grid.left, element.grid.top, element.grid.width, element.grid.height);
1879
1880
  }
1880
1881
  else {
@@ -1894,7 +1895,7 @@ export class TileRenderer {
1894
1895
  0 );
1895
1896
  }
1896
1897
  else {
1897
- context.fillStyle = this.theme.grid_cell?.fill ? ThemeColor(this.theme, this.theme.grid_cell.fill) : '';
1898
+ context.fillStyle = this.theme.grid_cell?.fill ? ResolveThemeColor(this.theme, this.theme.grid_cell.fill, 0) : '';
1898
1899
  context.fillRect(element.background.left, element.background.top,
1899
1900
  element.background.width, element.background.height);
1900
1901
  }
@@ -1924,7 +1925,7 @@ export class TileRenderer {
1924
1925
  context.lineWidth = 1;
1925
1926
 
1926
1927
  context.strokeStyle = context.fillStyle =
1927
- text_data.format ? text_data.format : ThemeColor2(this.theme, style.text, 1);
1928
+ text_data.format ? text_data.format : ResolveThemeColor(this.theme, style.text, 1);
1928
1929
 
1929
1930
  context.beginPath();
1930
1931