@rowsncolumns/spreadsheet 10.6.4 → 10.6.5

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.
Files changed (29) hide show
  1. package/dist/cjs/components/cell/alignment.d.ts +25 -0
  2. package/dist/cjs/components/cell/alignment.d.ts.map +1 -1
  3. package/dist/cjs/components/cell/alignment.js +39 -1
  4. package/dist/cjs/components/cell/cell-background.d.ts +16 -0
  5. package/dist/cjs/components/cell/cell-background.d.ts.map +1 -1
  6. package/dist/cjs/components/cell/cell-background.js +141 -54
  7. package/dist/cjs/components/cell/cell-text-runs.d.ts +12 -5
  8. package/dist/cjs/components/cell/cell-text-runs.d.ts.map +1 -1
  9. package/dist/cjs/components/cell/cell-text-runs.js +18 -20
  10. package/dist/cjs/components/cell/index.d.ts.map +1 -1
  11. package/dist/cjs/components/cell/index.js +20 -14
  12. package/dist/cjs/helpers.d.ts +5 -0
  13. package/dist/cjs/helpers.d.ts.map +1 -1
  14. package/dist/cjs/helpers.js +8 -4
  15. package/dist/esm/components/cell/alignment.d.ts +25 -0
  16. package/dist/esm/components/cell/alignment.d.ts.map +1 -1
  17. package/dist/esm/components/cell/alignment.js +33 -0
  18. package/dist/esm/components/cell/cell-background.d.ts +16 -0
  19. package/dist/esm/components/cell/cell-background.d.ts.map +1 -1
  20. package/dist/esm/components/cell/cell-background.js +106 -36
  21. package/dist/esm/components/cell/cell-text-runs.d.ts +12 -5
  22. package/dist/esm/components/cell/cell-text-runs.d.ts.map +1 -1
  23. package/dist/esm/components/cell/cell-text-runs.js +17 -22
  24. package/dist/esm/components/cell/index.d.ts.map +1 -1
  25. package/dist/esm/components/cell/index.js +17 -11
  26. package/dist/esm/helpers.d.ts +5 -0
  27. package/dist/esm/helpers.d.ts.map +1 -1
  28. package/dist/esm/helpers.js +8 -4
  29. package/package.json +2 -2
@@ -28,9 +28,9 @@ var LOADING_VALUE = "Loading...";
28
28
  // CSS-equivalent scale for sup/sub baseline offset (matches browser default).
29
29
  var BASELINE_OFFSET_FONT_SCALE = 0.58;
30
30
  exports.Cell = (0, react_1.memo)(function (props) {
31
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
32
- var x = props.x, y = props.y, width = props.width, height = props.height, value = props.value, _m = props.padding, padding = _m === void 0 ? grid_1.CELL_TEXT_PADDING : _m, _o = props.scale, scale = _o === void 0 ? 1 : _o, _p = props.lineHeight, lineHeight = _p === void 0 ? 1.2 : _p, _q = props.lineHeightMode, lineHeightMode = _q === void 0 ? "fontMetrics" : _q, imageUrl = props.imageUrl, cellFormat = props.cellFormat, chipBackgroundColor = props.chipBackgroundColor, defaultColor = props.defaultColor, defaultBackgroundColor = props.defaultBackgroundColor, sheetId = props.sheetId, rowIndex = props.rowIndex, columnIndex = props.columnIndex, onRequestEdit = props.onRequestEdit, onArrowClick = props.onArrowClick, isChecked = props.isChecked, isInvalid = props.isInvalid, isError = props.isError, showCheckbox = props.showCheckbox, showArrow = props.showArrow, showFilter = props.showFilter, showChip = props.showChip, showNote = props.showNote, showComment = props.showComment, isFilterActive = props.isFilterActive, filterIconColor = props.filterIconColor, onFilterClick = props.onFilterClick, onCheckboxClick = props.onCheckboxClick, enableOverflow = props.enableOverflow, cellWidth = props.cellWidth, _textWidth = props.textWidth, theme = props.theme, showCalculatedColumnIcon = props.showCalculatedColumnIcon, isCalculatedColumn = props.isCalculatedColumn, expandable = props.expandable, expanded = props.expanded, columnSpans = props.columnSpans, overflowRight = props.overflowRight, overflowLeft = props.overflowLeft, _r = props.centerOnSpan, centerOnSpan = _r === void 0 ? false : _r, _s = props.arrowOutside, arrowOutside = _s === void 0 ? false : _s, showGridLines = props.showGridLines, structuredValue = props.structuredValue, sparklineGroupAxis = props.sparklineGroupAxis, defaultFontSizePoint = props.defaultFontSizePoint, sortOrder = props.sortOrder, textFormatRuns = props.textFormatRuns, numberFormatLayout = props.numberFormatLayout, StructuredResult = props.StructuredResult, _t = props.readonly, readonly = _t === void 0 ? false : _t, onExpandCollapse = props.onExpandCollapse, getDefaultHorizontalAlignment = props.getDefaultHorizontalAlignment;
33
- var _u = cellFormat !== null && cellFormat !== void 0 ? cellFormat : {}, textFormat = _u.textFormat, wrapStrategy = _u.wrapStrategy;
31
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
32
+ var x = props.x, y = props.y, width = props.width, height = props.height, value = props.value, _r = props.padding, padding = _r === void 0 ? grid_1.CELL_TEXT_PADDING : _r, _s = props.scale, scale = _s === void 0 ? 1 : _s, _t = props.lineHeight, lineHeight = _t === void 0 ? 1.2 : _t, _u = props.lineHeightMode, lineHeightMode = _u === void 0 ? "fontMetrics" : _u, imageUrl = props.imageUrl, cellFormat = props.cellFormat, chipBackgroundColor = props.chipBackgroundColor, defaultColor = props.defaultColor, defaultBackgroundColor = props.defaultBackgroundColor, sheetId = props.sheetId, rowIndex = props.rowIndex, columnIndex = props.columnIndex, onRequestEdit = props.onRequestEdit, onArrowClick = props.onArrowClick, isChecked = props.isChecked, isInvalid = props.isInvalid, isError = props.isError, showCheckbox = props.showCheckbox, showArrow = props.showArrow, showFilter = props.showFilter, showChip = props.showChip, showNote = props.showNote, showComment = props.showComment, isFilterActive = props.isFilterActive, filterIconColor = props.filterIconColor, onFilterClick = props.onFilterClick, onCheckboxClick = props.onCheckboxClick, enableOverflow = props.enableOverflow, cellWidth = props.cellWidth, _textWidth = props.textWidth, theme = props.theme, showCalculatedColumnIcon = props.showCalculatedColumnIcon, isCalculatedColumn = props.isCalculatedColumn, expandable = props.expandable, expanded = props.expanded, columnSpans = props.columnSpans, overflowRight = props.overflowRight, overflowLeft = props.overflowLeft, _v = props.centerOnSpan, centerOnSpan = _v === void 0 ? false : _v, _w = props.arrowOutside, arrowOutside = _w === void 0 ? false : _w, showGridLines = props.showGridLines, structuredValue = props.structuredValue, sparklineGroupAxis = props.sparklineGroupAxis, defaultFontSizePoint = props.defaultFontSizePoint, sortOrder = props.sortOrder, textFormatRuns = props.textFormatRuns, numberFormatLayout = props.numberFormatLayout, StructuredResult = props.StructuredResult, _x = props.readonly, readonly = _x === void 0 ? false : _x, onExpandCollapse = props.onExpandCollapse, getDefaultHorizontalAlignment = props.getDefaultHorizontalAlignment;
33
+ var _y = cellFormat !== null && cellFormat !== void 0 ? cellFormat : {}, textFormat = _y.textFormat, wrapStrategy = _y.wrapStrategy;
34
34
  // openpyxl's `relativeIndent` is an additive delta on top of `indent`.
35
35
  var indent = ((_a = cellFormat === null || cellFormat === void 0 ? void 0 : cellFormat.indent) !== null && _a !== void 0 ? _a : 0) + ((_b = cellFormat === null || cellFormat === void 0 ? void 0 : cellFormat.relativeIndent) !== null && _b !== void 0 ? _b : 0);
36
36
  var conditionalIcon = (_c = cellFormat === null || cellFormat === void 0 ? void 0 : cellFormat.conditionalIcon) !== null && _c !== void 0 ? _c : null;
@@ -56,7 +56,7 @@ exports.Cell = (0, react_1.memo)(function (props) {
56
56
  var canvasTextAlign = (0, alignment_1.resolveCanvasTextAlign)(horizontalAlignment);
57
57
  var isFillAlignment = horizontalAlignment === "fill";
58
58
  // Text format
59
- var _v = textFormat !== null && textFormat !== void 0 ? textFormat : {}, colorObject = _v.color, bold = _v.bold, italic = _v.italic, strikethrough = _v.strikethrough, underline = _v.underline, underlineStyle = _v.underlineStyle, baselineOffset = _v.baselineOffset;
59
+ var _z = textFormat !== null && textFormat !== void 0 ? textFormat : {}, colorObject = _z.color, bold = _z.bold, italic = _z.italic, strikethrough = _z.strikethrough, underline = _z.underline, underlineStyle = _z.underlineStyle, baselineOffset = _z.baselineOffset;
60
60
  var fontSizePt = (_f = textFormat === null || textFormat === void 0 ? void 0 : textFormat.fontSize) !== null && _f !== void 0 ? _f : defaultFontSizePoint;
61
61
  // Fall back to the theme's body font so the painter agrees with the
62
62
  // sizer (AutoSizerCanvas measures with theme.primaryFontFamily).
@@ -77,11 +77,9 @@ exports.Cell = (0, react_1.memo)(function (props) {
77
77
  var fontSize = baselineOffset
78
78
  ? baseFontSize * BASELINE_OFFSET_FONT_SCALE
79
79
  : baseFontSize;
80
- var effectiveVerticalAlignment = baselineOffset === "superscript"
81
- ? "top"
82
- : baselineOffset === "subscript"
83
- ? "bottom"
84
- : verticalAlignment;
80
+ // Superscript / subscript keep the cell's alignment and move the
81
+ // baseline instead (`scriptOffsetY` below), as Excel does.
82
+ var effectiveVerticalAlignment = verticalAlignment;
85
83
  var textStyle = "".concat(bold ? "bold" : "normal", " ").concat(italic ? "italic" : "normal");
86
84
  var showText = !(0, utils_1.isNil)(structuredValue) ? false : !(0, utils_1.isNil)(value);
87
85
  // Overflow line
@@ -316,11 +314,19 @@ exports.Cell = (0, react_1.memo)(function (props) {
316
314
  // own styling instead of being flattened; plain no-run cells with
317
315
  // a cell-level baselineOffset keep the single-style approximation
318
316
  // below (scaled font + top/bottom alignment).
317
+ // Shrink-to-fit and rotated cells keep their runs: the run painter takes
318
+ // the shrink factor and the rotated layout (stacked text stays plain).
319
319
  var useRichTextRunPath = !showChip &&
320
- !shrinkEnabled &&
321
320
  !isStackedVertical &&
322
- !hasNumericRotation &&
323
321
  (0, rich_text_1.hasRenderableRuns)(textFormatRuns !== null && textFormatRuns !== void 0 ? textFormatRuns : undefined);
322
+ var shrinkFactor = fontSize > 0 ? effectiveFontSize / fontSize : 1;
323
+ var scriptOffsetY = (0, alignment_1.getScriptTextOffsetY)({
324
+ baselineOffset: baselineOffset,
325
+ verticalAlign: effectiveVerticalAlignment,
326
+ baseFontSize: baseFontSize * shrinkFactor,
327
+ scriptFontSize: effectiveFontSize,
328
+ lineHeight: textLineHeight,
329
+ });
324
330
  // Double / accounting underlines on a single unrotated line (the default
325
331
  // Text path); wrapped, rotated or rich-text cells keep Konva's single line.
326
332
  var paintStyledUnderline = hasStyledUnderline &&
@@ -605,14 +611,14 @@ exports.Cell = (0, react_1.memo)(function (props) {
605
611
  // lines, and `textFormatRuns` indices reference the raw
606
612
  // string. `normalizeDisplayText` is bypassed because the
607
613
  // renderer handles multi-line layout itself.
608
- react_1.default.createElement(cell_text_runs_1.CellTextRuns, { x: textLeftPadding, y: textNode.y, width: finalTextWidth, height: textNode.height, padding: padding, value: displayValue !== null && displayValue !== void 0 ? displayValue : "", runs: textFormatRuns !== null && textFormatRuns !== void 0 ? textFormatRuns : [], baseColor: color !== null && color !== void 0 ? color : defaultColor, baseFontFamily: fontFamily,
614
+ react_1.default.createElement(cell_text_runs_1.CellTextRuns, { x: (_j = rotatedLayout === null || rotatedLayout === void 0 ? void 0 : rotatedLayout.x) !== null && _j !== void 0 ? _j : textLeftPadding, y: (_k = rotatedLayout === null || rotatedLayout === void 0 ? void 0 : rotatedLayout.y) !== null && _k !== void 0 ? _k : textNode.y, width: (_l = rotatedLayout === null || rotatedLayout === void 0 ? void 0 : rotatedLayout.width) !== null && _l !== void 0 ? _l : finalTextWidth, height: rotatedLayout ? approxTextHeight : textNode.height, rotation: rotatedLayout ? rotationDegrees : undefined, fontScale: scale * shrinkFactor, padding: padding, value: displayValue !== null && displayValue !== void 0 ? displayValue : "", runs: textFormatRuns !== null && textFormatRuns !== void 0 ? textFormatRuns : [], baseColor: color !== null && color !== void 0 ? color : defaultColor, baseFontFamily: fontFamily,
609
615
  // UN-scaled size on purpose: when the cell carries a
610
616
  // baselineOffset the segment resolver applies the
611
617
  // sup/sub font scale itself (exactly once). Shrink-to-
612
618
  // fit never reaches this path, so `baseFontSize` equals
613
619
  // `effectiveFontSize` for every other cell.
614
- baseFontSize: baseFontSize, baseBold: !!bold, baseItalic: !!italic, baseUnderline: !!underline, baseStrikethrough: !!strikethrough, baseBaselineOffset: baselineOffset !== null && baselineOffset !== void 0 ? baselineOffset : undefined, horizontalAlign: canvasTextAlign, verticalAlign: effectiveVerticalAlignment, lineHeight: lineHeight, lineHeightMode: lineHeightMode, scale: scale, wrap: shouldWrap, theme: theme })) : paintDistributed ? (react_1.default.createElement(react_konva_1.Shape, { x: textLeftPadding, y: textNode.y, width: finalTextWidth, height: textNode.height, sceneFunc: distributedSceneFunc, listening: false, perfectDrawEnabled: false })) : paintNumberFormatLayout ? (react_1.default.createElement(react_konva_1.Shape, { x: textLeftPadding, y: textNode.y, width: finalTextWidth, height: textNode.height, sceneFunc: numberFormatSceneFunc, listening: false, perfectDrawEnabled: false })) : (react_1.default.createElement(react_1.default.Fragment, null,
615
- react_1.default.createElement(react_konva_1.Text, { x: (_j = rotatedLayout === null || rotatedLayout === void 0 ? void 0 : rotatedLayout.x) !== null && _j !== void 0 ? _j : textLeftPadding, y: (_k = rotatedLayout === null || rotatedLayout === void 0 ? void 0 : rotatedLayout.y) !== null && _k !== void 0 ? _k : textNode.y, offsetX: rotatedLayout === null || rotatedLayout === void 0 ? void 0 : rotatedLayout.offsetX, offsetY: rotatedLayout === null || rotatedLayout === void 0 ? void 0 : rotatedLayout.offsetY, height: rotatedLayout ? approxTextHeight : textNode.height, width: (_l = rotatedLayout === null || rotatedLayout === void 0 ? void 0 : rotatedLayout.width) !== null && _l !== void 0 ? _l : finalTextWidth, text: displayValue, fill: color !== null && color !== void 0 ? color : defaultColor, verticalAlign: rotatedLayout ? "top" : effectiveVerticalAlignment, align: rotatedLayout ? "left" : canvasTextAlign, fontFamily: fontFamily, fontStyle: textStyle, fontSize: effectiveFontSize, textDecoration: paintStyledUnderline ? textDecorationFor(false) : textDecoration, padding: padding, wrap: textWrapStrategy, lineHeight: textLineHeight, rotation: rotationDegrees, direction: textDirection, hitStrokeWidth: 0, perfectDrawEnabled: false }),
620
+ baseFontSize: baseFontSize * shrinkFactor, baseBold: !!bold, baseItalic: !!italic, baseUnderline: !!underline, baseStrikethrough: !!strikethrough, baseBaselineOffset: baselineOffset !== null && baselineOffset !== void 0 ? baselineOffset : undefined, horizontalAlign: rotatedLayout ? "left" : canvasTextAlign, verticalAlign: rotatedLayout ? "top" : effectiveVerticalAlignment, lineHeight: lineHeight, lineHeightMode: lineHeightMode, scale: scale, wrap: shouldWrap && !rotatedLayout, theme: theme })) : paintDistributed ? (react_1.default.createElement(react_konva_1.Shape, { x: textLeftPadding, y: textNode.y, width: finalTextWidth, height: textNode.height, sceneFunc: distributedSceneFunc, listening: false, perfectDrawEnabled: false })) : paintNumberFormatLayout ? (react_1.default.createElement(react_konva_1.Shape, { x: textLeftPadding, y: textNode.y, width: finalTextWidth, height: textNode.height, sceneFunc: numberFormatSceneFunc, listening: false, perfectDrawEnabled: false })) : (react_1.default.createElement(react_1.default.Fragment, null,
621
+ react_1.default.createElement(react_konva_1.Text, { x: (_m = rotatedLayout === null || rotatedLayout === void 0 ? void 0 : rotatedLayout.x) !== null && _m !== void 0 ? _m : textLeftPadding, y: (_o = rotatedLayout === null || rotatedLayout === void 0 ? void 0 : rotatedLayout.y) !== null && _o !== void 0 ? _o : textNode.y, offsetX: rotatedLayout === null || rotatedLayout === void 0 ? void 0 : rotatedLayout.offsetX, offsetY: ((_p = rotatedLayout === null || rotatedLayout === void 0 ? void 0 : rotatedLayout.offsetY) !== null && _p !== void 0 ? _p : 0) + scriptOffsetY, height: rotatedLayout ? approxTextHeight : textNode.height, width: (_q = rotatedLayout === null || rotatedLayout === void 0 ? void 0 : rotatedLayout.width) !== null && _q !== void 0 ? _q : finalTextWidth, text: displayValue, fill: color !== null && color !== void 0 ? color : defaultColor, verticalAlign: rotatedLayout ? "top" : effectiveVerticalAlignment, align: rotatedLayout ? "left" : canvasTextAlign, fontFamily: fontFamily, fontStyle: textStyle, fontSize: effectiveFontSize, textDecoration: paintStyledUnderline ? textDecorationFor(false) : textDecoration, padding: padding, wrap: textWrapStrategy, lineHeight: textLineHeight, rotation: rotationDegrees, direction: textDirection, hitStrokeWidth: 0, perfectDrawEnabled: false }),
616
622
  paintStyledUnderline ? (react_1.default.createElement(react_konva_1.Shape, { sceneFunc: underlineSceneFunc, listening: false, perfectDrawEnabled: false })) : null)))) : imageUrl ? (react_1.default.createElement(grid_1.Image, { x: x, y: y, spacing: 1, width: width, height: height, url: imageUrl, perfectDrawEnabled: false, horizontalAlignment: canvasTextAlign === "justify" ? "left" : canvasTextAlign, verticalAlignment: verticalAlignment })) : null,
617
623
  showFilter ? (react_1.default.createElement(cell_filter_1.CellFilter, { scale: scale, isActive: isFilterActive, onClick: readonly ? undefined : onFilterClick, rowIndex: props.rowIndex, columnIndex: props.columnIndex, x: x, y: y, height: height, width: width, filterIconColor: filterIconColor, verticalAlignment: verticalAlignment, backgroundColor: defaultBackgroundColor, sortOrder: sortOrder })) : showArrow && !readonly ? (react_1.default.createElement(cell_arrow_1.CellArrow, { scale: scale, onClick: onArrowClick !== null && onArrowClick !== void 0 ? onArrowClick : onRequestEdit, rowIndex: rowIndex, columnIndex: columnIndex, x: arrowOutside ? x + (config_1.ARROW_DOWN_WIDTH + 4) * scale : x, y: y, height: height, width: width, verticalAlignment: verticalAlignment })) : null,
618
624
  expandable ? (react_1.default.createElement(cell_group_1.CellGroup, { scale: scale, onClick: function (cell) {
@@ -3,6 +3,11 @@ import type { CellTooltipVariants } from "@rowsncolumns/ui";
3
3
  import type { AXIS, Border, CellData, Color, ConditionType, ConditionValue, FilterSpec, FilterView, HorizontalAlign, Sheet, SheetCoordinate, SheetRange, SortOrder, StructuredValue, StyleReference, TableTheme, TableView, VerticalAlign } from "./types";
4
4
  export declare const isFirefox: boolean;
5
5
  export declare const isMac: boolean;
6
+ /**
7
+ * Converts a font size in points to CSS pixels: 96 px per inch over 72 pt
8
+ * per inch, unrounded, so 11 pt is 14.67 px as Excel paints it at 100 %
9
+ * (a rounded `1.3 × pt` made 11 pt 14 px and 24 pt 31 px).
10
+ */
6
11
  export declare const pointToPixel: (pt: number) => number;
7
12
  export declare const pixelToPoint: (px: number) => number;
8
13
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../helpers.ts"],"names":[],"mappings":"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"}
@@ -12,11 +12,15 @@ exports.isFirefox = grid_1.canUseDOM
12
12
  : false;
13
13
  // Check if platform is macOS, where Ctrl+click is the context menu gesture
14
14
  exports.isMac = (0, platform_1.isMacPlatform)();
15
- /* Converts point to pixel */
16
- var pointToPixel = function (pt) { return Math.round((13 / 10) * pt); };
15
+ /**
16
+ * Converts a font size in points to CSS pixels: 96 px per inch over 72 pt
17
+ * per inch, unrounded, so 11 pt is 14.67 px as Excel paints it at 100 %
18
+ * (a rounded `1.3 × pt` made 11 pt 14 px and 24 pt 31 px).
19
+ */
20
+ var pointToPixel = function (pt) { return (pt * 96) / 72; };
17
21
  exports.pointToPixel = pointToPixel;
18
- /* Convert pixel to point */
19
- var pixelToPoint = function (px) { return Math.round((px / 13) * 10); };
22
+ /* Convert pixel to (whole) points */
23
+ var pixelToPoint = function (px) { return Math.round((px * 72) / 96); };
20
24
  exports.pixelToPoint = pixelToPoint;
21
25
  /**
22
26
  * Normalize text for display by replacing newlines with spaces.
@@ -154,4 +154,29 @@ export type DistributedWord = {
154
154
  * the words of each line with their x inside `width`.
155
155
  */
156
156
  export declare const layoutDistributedLines: (text: string, width: number, measure: (text: string) => number) => DistributedWord[][];
157
+ /**
158
+ * Excel's superscript sits on a baseline raised by a third of the line's
159
+ * font size, subscript on one dropped by about a seventh (Format Cells ▸
160
+ * Font ▸ Effects): a true baseline shift, not the glyphs pushed to the top
161
+ * or bottom of the cell.
162
+ */
163
+ export declare const SUPERSCRIPT_RISE_EM = 0.33;
164
+ export declare const SUBSCRIPT_DROP_EM = 0.14;
165
+ /** Baseline shift (px, down positive) of a sup/sub run on a `lineFontSize` line. */
166
+ export declare const getScriptBaselineShift: (baselineOffset: "superscript" | "subscript" | string | null | undefined, lineFontSize: number) => number;
167
+ /**
168
+ * Konva `offsetY` (up positive) for a cell whose whole text is superscript /
169
+ * subscript: the text node draws the smaller script font aligned like the
170
+ * cell, and this moves its baseline to where Excel puts it — the base
171
+ * font's baseline in that alignment, shifted by
172
+ * {@link getScriptBaselineShift}.
173
+ */
174
+ export declare const getScriptTextOffsetY: ({ baselineOffset, verticalAlign, baseFontSize, scriptFontSize, lineHeight, }: {
175
+ baselineOffset: "superscript" | "subscript" | string | null | undefined;
176
+ verticalAlign: "top" | "middle" | "bottom";
177
+ baseFontSize: number;
178
+ scriptFontSize: number;
179
+ /** Line-box multiple of the font size the text node uses. */
180
+ lineHeight: number;
181
+ }) => number;
157
182
  //# sourceMappingURL=alignment.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"alignment.d.ts","sourceRoot":"","sources":["../../../../components/cell/alignment.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"alignment.d.ts","sourceRoot":"","sources":["../../../../components/cell/alignment.ts"],"names":[],"mappings":"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"}
@@ -285,3 +285,36 @@ export const layoutDistributedLines = (text, width, measure) => {
285
285
  }
286
286
  return lines;
287
287
  };
288
+ /**
289
+ * Excel's superscript sits on a baseline raised by a third of the line's
290
+ * font size, subscript on one dropped by about a seventh (Format Cells ▸
291
+ * Font ▸ Effects): a true baseline shift, not the glyphs pushed to the top
292
+ * or bottom of the cell.
293
+ */
294
+ export const SUPERSCRIPT_RISE_EM = 0.33;
295
+ export const SUBSCRIPT_DROP_EM = 0.14;
296
+ /** Baseline shift (px, down positive) of a sup/sub run on a `lineFontSize` line. */
297
+ export const getScriptBaselineShift = (baselineOffset, lineFontSize) => baselineOffset === "superscript"
298
+ ? -SUPERSCRIPT_RISE_EM * lineFontSize
299
+ : baselineOffset === "subscript"
300
+ ? SUBSCRIPT_DROP_EM * lineFontSize
301
+ : 0;
302
+ /** Distance from a Konva line box's top to its alphabetic baseline, ≈. */
303
+ const BASELINE_BELOW_CENTRE_EM = 0.35;
304
+ /**
305
+ * Konva `offsetY` (up positive) for a cell whose whole text is superscript /
306
+ * subscript: the text node draws the smaller script font aligned like the
307
+ * cell, and this moves its baseline to where Excel puts it — the base
308
+ * font's baseline in that alignment, shifted by
309
+ * {@link getScriptBaselineShift}.
310
+ */
311
+ export const getScriptTextOffsetY = ({ baselineOffset, verticalAlign, baseFontSize, scriptFontSize, lineHeight, }) => {
312
+ if (baselineOffset !== "superscript" && baselineOffset !== "subscript") {
313
+ return 0;
314
+ }
315
+ const boxDelta = ((baseFontSize - scriptFontSize) * lineHeight) / 2;
316
+ const centreDelta = BASELINE_BELOW_CENTRE_EM * (baseFontSize - scriptFontSize);
317
+ const alignDelta = verticalAlign === "top" ? boxDelta : verticalAlign === "bottom" ? -boxDelta : 0;
318
+ const down = alignDelta + centreDelta + getScriptBaselineShift(baselineOffset, baseFontSize);
319
+ return -down;
320
+ };
@@ -12,6 +12,22 @@ type CellBackgroundProps = RendererProps & {
12
12
  foregroundColor?: string;
13
13
  gradient?: GradientFill | null;
14
14
  };
15
+ export type PathGradientRegion = {
16
+ /** Polygon to fill, in shape coordinates. */
17
+ points: [number, number][];
18
+ /** Gradient axis: inner stop at (x0, y0), outer stop at (x1, y1). */
19
+ axis: [number, number, number, number];
20
+ };
21
+ /**
22
+ * Excel's path gradient over the rectangle `[x0, y0]–[x1, y1]`: the core
23
+ * rectangle (inner stop colour) and four trapezoids cut along the
24
+ * core-to-corner diagonals, each a linear gradient from the core edge out
25
+ * to its cell edge — together, concentric rectangles of colour.
26
+ */
27
+ export declare const getPathGradientRegions: (gradient: Pick<GradientFill, "left" | "right" | "top" | "bottom">, x0: number, y0: number, x1: number, y1: number) => {
28
+ core: [number, number, number, number];
29
+ regions: PathGradientRegion[];
30
+ };
15
31
  export declare const CellBackground: ({ x, y, width, height, backgroundColor, defaultBackgroundColor, scale, showGridLines, isMergedCell, fillPattern, foregroundColor, gradient, }: CellBackgroundProps) => React.JSX.Element;
16
32
  export {};
17
33
  //# sourceMappingURL=cell-background.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cell-background.d.ts","sourceRoot":"","sources":["../../../../components/cell/cell-background.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAIxD,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE7D,6EAA6E;AAC7E,eAAO,MAAM,uBAAuB,YAAY,CAAC;AAEjD,KAAK,mBAAmB,GAAG,aAAa,GAAG;IACzC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;CAChC,CAAC;AAmFF,eAAO,MAAM,cAAc,GAAI,+IAa5B,mBAAmB,sBAwFrB,CAAC"}
1
+ {"version":3,"file":"cell-background.d.ts","sourceRoot":"","sources":["../../../../components/cell/cell-background.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAIxD,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE7D,6EAA6E;AAC7E,eAAO,MAAM,uBAAuB,YAAY,CAAC;AAEjD,KAAK,mBAAmB,GAAG,aAAa,GAAG;IACzC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;CAChC,CAAC;AAWF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,6CAA6C;IAC7C,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IAC3B,qEAAqE;IACrE,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GACjC,UAAU,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC,EACjE,IAAI,MAAM,EACV,IAAI,MAAM,EACV,IAAI,MAAM,EACV,IAAI,MAAM,KACT;IAAE,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,OAAO,EAAE,kBAAkB,EAAE,CAAA;CAoDzE,CAAC;AAkFF,eAAO,MAAM,cAAc,GAAI,+IAa5B,mBAAmB,sBAmGrB,CAAC"}
@@ -4,30 +4,100 @@ import { Shape } from "react-konva";
4
4
  import { getPatternCanvas } from "../../api/fill-patterns";
5
5
  /** Excel's Automatic pattern colour: a pattern with no colour of its own. */
6
6
  export const AUTOMATIC_PATTERN_COLOR = "#000000";
7
- // Build a CanvasGradient matching the OOXML <gradientFill> spec.
8
- // linear: `degree` rotates the axis (0 = left→right, 90 = top→bottom,
9
- // 180 = right→left, 270 = bottom→top). Excel's axis runs through the
10
- // cell's centroid at the given angle and the gradient spans the full
11
- // cell along it.
12
- // path: rectangular radial — `left`/`right`/`top`/`bottom` (each 0..1)
13
- // describe the inset of the inner stop's "core" rectangle. We
14
- // approximate as a single radial gradient anchored at that core's
15
- // center, with radius = distance to the farthest corner.
7
+ /**
8
+ * Excel's path gradient over the rectangle `[x0, y0]–[x1, y1]`: the core
9
+ * rectangle (inner stop colour) and four trapezoids cut along the
10
+ * core-to-corner diagonals, each a linear gradient from the core edge out
11
+ * to its cell edge — together, concentric rectangles of colour.
12
+ */
13
+ export const getPathGradientRegions = (gradient, x0, y0, x1, y1) => {
14
+ const width = x1 - x0;
15
+ const height = y1 - y0;
16
+ const cl = x0 + (gradient.left ?? 0) * width;
17
+ const cr = x1 - (gradient.right ?? 0) * width;
18
+ const ct = y0 + (gradient.top ?? 0) * height;
19
+ const cb = y1 - (gradient.bottom ?? 0) * height;
20
+ const coreLeft = Math.min(cl, cr);
21
+ const coreRight = Math.max(cl, cr);
22
+ const coreTop = Math.min(ct, cb);
23
+ const coreBottom = Math.max(ct, cb);
24
+ return {
25
+ core: [coreLeft, coreTop, coreRight, coreBottom],
26
+ regions: [
27
+ {
28
+ points: [
29
+ [x0, y0],
30
+ [x1, y0],
31
+ [coreRight, coreTop],
32
+ [coreLeft, coreTop],
33
+ ],
34
+ axis: [coreLeft, coreTop, coreLeft, y0],
35
+ },
36
+ {
37
+ points: [
38
+ [x1, y0],
39
+ [x1, y1],
40
+ [coreRight, coreBottom],
41
+ [coreRight, coreTop],
42
+ ],
43
+ axis: [coreRight, coreTop, x1, coreTop],
44
+ },
45
+ {
46
+ points: [
47
+ [x1, y1],
48
+ [x0, y1],
49
+ [coreLeft, coreBottom],
50
+ [coreRight, coreBottom],
51
+ ],
52
+ axis: [coreLeft, coreBottom, coreLeft, y1],
53
+ },
54
+ {
55
+ points: [
56
+ [x0, y1],
57
+ [x0, y0],
58
+ [coreLeft, coreTop],
59
+ [coreLeft, coreBottom],
60
+ ],
61
+ axis: [coreLeft, coreTop, x0, coreTop],
62
+ },
63
+ ],
64
+ };
65
+ };
66
+ const addStops = (canvasGrad, gradient) => {
67
+ for (const stop of gradient.stops) {
68
+ // Clamp position to [0,1] — Canvas API rejects out-of-range values.
69
+ const pos = Math.max(0, Math.min(1, stop.position));
70
+ try {
71
+ canvasGrad.addColorStop(pos, stop.color);
72
+ }
73
+ catch {
74
+ // Invalid color string — skip rather than blow up the render.
75
+ }
76
+ }
77
+ };
78
+ const paintPathGradient = (context, native, gradient, rect) => {
79
+ const { core, regions } = getPathGradientRegions(gradient, ...rect);
80
+ const sorted = [...gradient.stops].sort((a, b) => a.position - b.position);
81
+ context.setAttr("fillStyle", sorted[0].color);
82
+ context.fillRect(core[0], core[1], core[2] - core[0], core[3] - core[1]);
83
+ for (const region of regions) {
84
+ const [ax0, ay0, ax1, ay1] = region.axis;
85
+ if (ax0 === ax1 && ay0 === ay1)
86
+ continue;
87
+ const canvasGrad = native.createLinearGradient(ax0, ay0, ax1, ay1);
88
+ addStops(canvasGrad, gradient);
89
+ context.beginPath();
90
+ region.points.forEach(([px, py], index) => index ? context.lineTo(px, py) : context.moveTo(px, py));
91
+ context.closePath();
92
+ context.setAttr("fillStyle", canvasGrad);
93
+ context.fill();
94
+ }
95
+ };
16
96
  const buildCanvasGradient = (native, gradient, width, height) => {
17
97
  if (!gradient.stops?.length)
18
98
  return null;
19
99
  let canvasGrad;
20
- if (gradient.type === "path") {
21
- const left = gradient.left ?? 0;
22
- const right = gradient.right ?? 0;
23
- const top = gradient.top ?? 0;
24
- const bottom = gradient.bottom ?? 0;
25
- const cx = ((left + (1 - right)) / 2) * width;
26
- const cy = ((top + (1 - bottom)) / 2) * height;
27
- const farthestCorner = Math.max(Math.hypot(cx, cy), Math.hypot(width - cx, cy), Math.hypot(cx, height - cy), Math.hypot(width - cx, height - cy));
28
- canvasGrad = native.createRadialGradient(cx, cy, 0, cx, cy, farthestCorner || 1);
29
- }
30
- else {
100
+ {
31
101
  // Linear. Map degrees → axis vector. Excel: degree=0 runs the
32
102
  // gradient from LEFT to RIGHT. degree increases clockwise.
33
103
  const deg = (((gradient.degree ?? 0) % 360) + 360) % 360;
@@ -60,16 +130,7 @@ const buildCanvasGradient = (native, gradient, width, height) => {
60
130
  const y1 = cy + dy * maxProj;
61
131
  canvasGrad = native.createLinearGradient(x0, y0, x1, y1);
62
132
  }
63
- for (const stop of gradient.stops) {
64
- // Clamp position to [0,1] — Canvas API rejects out-of-range values.
65
- const pos = Math.max(0, Math.min(1, stop.position));
66
- try {
67
- canvasGrad.addColorStop(pos, stop.color);
68
- }
69
- catch {
70
- // Invalid color string — skip rather than blow up the render.
71
- }
72
- }
133
+ addStops(canvasGrad, gradient);
73
134
  return canvasGrad;
74
135
  };
75
136
  export const CellBackground = ({ x, y, width, height, backgroundColor, defaultBackgroundColor, scale, showGridLines, isMergedCell, fillPattern, foregroundColor, gradient, }) => {
@@ -96,7 +157,14 @@ export const CellBackground = ({ x, y, width, height, backgroundColor, defaultBa
96
157
  const useTile = fillPattern && fillPattern !== "solid" && fillPattern !== "none";
97
158
  const useGradient = !!gradient && (gradient.stops?.length ?? 0) > 0;
98
159
  const native = context._context;
99
- if (useGradient && native) {
160
+ const fillRectArea = (isMergedCell || !showFaintBorder) && showGridLines
161
+ ? [1, 1, shape.width(), shape.height()]
162
+ : [0, 0, shape.width() + 1, shape.height() + 1];
163
+ const usePathGradient = useGradient && native && gradient.type === "path";
164
+ if (usePathGradient) {
165
+ paintPathGradient(context, native, gradient, fillRectArea);
166
+ }
167
+ else if (useGradient && native) {
100
168
  const canvasGrad = buildCanvasGradient(native, gradient, shape.width(), shape.height());
101
169
  if (canvasGrad) {
102
170
  context.setAttr("fillStyle", canvasGrad);
@@ -121,11 +189,13 @@ export const CellBackground = ({ x, y, width, height, backgroundColor, defaultBa
121
189
  else {
122
190
  context.setAttr("fillStyle", finalBackgroundColor);
123
191
  }
124
- if ((isMergedCell || !showFaintBorder) && showGridLines) {
125
- context.fillRect(1, 1, shape.width() - 1, shape.height() - 1);
126
- }
127
- else {
128
- context.fillRect(0, 0, shape.width() + 1, shape.height() + 1);
192
+ if (!usePathGradient) {
193
+ if ((isMergedCell || !showFaintBorder) && showGridLines) {
194
+ context.fillRect(1, 1, shape.width() - 1, shape.height() - 1);
195
+ }
196
+ else {
197
+ context.fillRect(0, 0, shape.width() + 1, shape.height() + 1);
198
+ }
129
199
  }
130
200
  if (showFaintBorder) {
131
201
  const lightColor = lightenColor(-0.1, backgroundColor);
@@ -46,6 +46,13 @@ export type CellTextRunsProps = {
46
46
  wrap: boolean;
47
47
  /** Theme — used to resolve segment `color` objects to CSS strings. */
48
48
  theme: SpreadsheetTheme;
49
+ /**
50
+ * Multiplier for run font sizes given in points (zoom × shrink-to-fit),
51
+ * so a run's own size follows the cell's.
52
+ */
53
+ fontScale?: number;
54
+ /** Konva rotation (degrees, clockwise) of the whole block — rotated text. */
55
+ rotation?: number;
49
56
  };
50
57
  export type Resolved = {
51
58
  bold: boolean;
@@ -64,7 +71,7 @@ export type Resolved = {
64
71
  * merged style carries a `baselineOffset` (own or inherited from the
65
72
  * base) the sup/sub font scale is applied here, exactly once.
66
73
  */
67
- export declare const resolveSegmentStyle: (seg: RichTextSegment, base: Resolved, theme: SpreadsheetTheme) => Resolved;
74
+ export declare const resolveSegmentStyle: (seg: RichTextSegment, base: Resolved, theme: SpreadsheetTheme, fontScale?: number) => Resolved;
68
75
  /** A segment paired with its fully-resolved paint style. */
69
76
  export type ResolvedSegment = {
70
77
  seg: RichTextSegment;
@@ -83,10 +90,10 @@ export declare const computeLineMetrics: (resolvedLines: ResolvedSegment[][], ba
83
90
  };
84
91
  /**
85
92
  * Vertical draw position (textBaseline="top") for one segment within
86
- * its line box. Normal runs share the line's alphabetic baseline
87
- * (smaller runs shift down), superscript hugs the line top, subscript
88
- * hugs the line bottom. All three reduce to `lineTop` when the run's
89
- * size equals the line's. Exported for unit tests.
93
+ * its line box. Every run shares the line's alphabetic baseline (smaller
94
+ * runs shift down); superscript / subscript runs then move that baseline
95
+ * up / down by Excel's shift ({@link getScriptBaselineShift}). Exported
96
+ * for unit tests.
90
97
  */
91
98
  export declare const computeSegmentTop: (lineTop: number, lineFontSize: number, segFontSize: number, baselineOffset: "superscript" | "subscript" | undefined) => number;
92
99
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"cell-text-runs.d.ts","sourceRoot":"","sources":["../../../../components/cell/cell-text-runs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGzD,OAAO,KAAsB,MAAM,OAAO,CAAC;AAG3C,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAElE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACxB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,iBAAiB,GAAG;IAC9B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,kBAAkB,EAAE,CAAC;IAC3B,8DAA8D;IAC9D,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,sEAAsE;IACtE,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,iBAAiB,EAAE,OAAO,CAAC;IAC3B;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,aAAa,GAAG,WAAW,CAAC;IACjD,eAAe,EAAE,eAAe,CAAC;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,+EAA+E;IAC/E,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,cAAc,CAAC;IAC/B,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,IAAI,EAAE,OAAO,CAAC;IACd,sEAAsE;IACtE,KAAK,EAAE,gBAAgB,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,aAAa,GAAG,WAAW,CAAC;CAC9C,CAAC;AAkCF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAC9B,KAAK,eAAe,EACpB,MAAM,QAAQ,EACd,OAAO,gBAAgB,KACtB,QA0BF,CAAC;AAKF,4DAA4D;AAC5D,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,EAAE,eAAe,CAAC;IACrB,CAAC,EAAE,QAAQ,CAAC;CACb,CAAC;AAYF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,eAAe,eAAe,EAAE,EAAE,EAClC,MAAM,QAAQ,EACd,WAAW,CAAC,CAAC,EAAE,QAAQ,KAAK,MAAM,KACjC;IAAE,aAAa,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CASvE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAC5B,SAAS,MAAM,EACf,cAAc,MAAM,EACpB,aAAa,MAAM,EACnB,gBAAgB,aAAa,GAAG,WAAW,GAAG,SAAS,KACtD,MAMF,CAAC;AAoHF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,YAAY,oCAAsB,iBAAiB,uBA2P9D,CAAC"}
1
+ {"version":3,"file":"cell-text-runs.d.ts","sourceRoot":"","sources":["../../../../components/cell/cell-text-runs.tsx"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import React, { useCallback } from "react";
2
2
  import { Shape } from "react-konva";
3
3
  import { getStringifiedColor, resolveThemeFontFamily } from "../../themes";
4
+ import { getScriptBaselineShift } from "./alignment";
4
5
  import { getLineAdvance } from "./line-height";
5
6
  import { buildRichTextSegments, segmentsToLines, segmentToAtoms, } from "./rich-text";
6
7
  const BASELINE_OFFSET_FONT_SCALE = 0.58;
@@ -39,12 +40,10 @@ const buildFontString = (r) => {
39
40
  * merged style carries a `baselineOffset` (own or inherited from the
40
41
  * base) the sup/sub font scale is applied here, exactly once.
41
42
  */
42
- export const resolveSegmentStyle = (seg, base, theme) => {
43
+ export const resolveSegmentStyle = (seg, base, theme, fontScale = 1) => {
43
44
  const f = seg.format;
44
45
  const baselineOffset = f.baselineOffset ?? base.baselineOffset;
45
- const fontSize = typeof f.fontSize === "number"
46
- ? (f.fontSize / pointFromPx(base.fontSize)) * base.fontSize
47
- : base.fontSize;
46
+ const fontSize = typeof f.fontSize === "number" ? f.fontSize * PT_TO_PX * fontScale : base.fontSize;
48
47
  return {
49
48
  bold: f.bold ?? base.bold,
50
49
  italic: f.italic ?? base.italic,
@@ -64,8 +63,8 @@ export const resolveSegmentStyle = (seg, base, theme) => {
64
63
  baselineOffset,
65
64
  };
66
65
  };
67
- /** Inverse of pointToPixel — used only when computing a per-segment scale. */
68
- const pointFromPx = (px) => px / 1.3333;
66
+ /** CSS pixels per point (96 / 72), as `pointToPixel`. */
67
+ const PT_TO_PX = 96 / 72;
69
68
  /**
70
69
  * Fraction of the em box above the alphabetic baseline for typical
71
70
  * Latin fonts. Used to baseline-align mixed-size runs on one line:
@@ -89,19 +88,14 @@ export const computeLineMetrics = (resolvedLines, base, advanceOf) => {
89
88
  };
90
89
  /**
91
90
  * Vertical draw position (textBaseline="top") for one segment within
92
- * its line box. Normal runs share the line's alphabetic baseline
93
- * (smaller runs shift down), superscript hugs the line top, subscript
94
- * hugs the line bottom. All three reduce to `lineTop` when the run's
95
- * size equals the line's. Exported for unit tests.
91
+ * its line box. Every run shares the line's alphabetic baseline (smaller
92
+ * runs shift down); superscript / subscript runs then move that baseline
93
+ * up / down by Excel's shift ({@link getScriptBaselineShift}). Exported
94
+ * for unit tests.
96
95
  */
97
- export const computeSegmentTop = (lineTop, lineFontSize, segFontSize, baselineOffset) => {
98
- if (baselineOffset === "superscript")
99
- return lineTop;
100
- if (baselineOffset === "subscript") {
101
- return lineTop + (lineFontSize - segFontSize);
102
- }
103
- return lineTop + (lineFontSize - segFontSize) * ALPHABETIC_BASELINE_RATIO;
104
- };
96
+ export const computeSegmentTop = (lineTop, lineFontSize, segFontSize, baselineOffset) => lineTop +
97
+ (lineFontSize - segFontSize) * ALPHABETIC_BASELINE_RATIO +
98
+ getScriptBaselineShift(baselineOffset, lineFontSize);
105
99
  /**
106
100
  * Sum of advance widths of a single line of resolved segments, using
107
101
  * the supplied context's `measureText`. Mutates ctx font as it walks
@@ -214,7 +208,7 @@ const atomsToSegments = (atoms) => {
214
208
  * - Mention runs render as their inline label only (no chrome).
215
209
  */
216
210
  export const CellTextRuns = React.memo((props) => {
217
- const { x, y, width, height, padding, value, runs, baseColor, baseFontFamily, baseFontSize, baseBold, baseItalic, baseUnderline, baseStrikethrough, baseBaselineOffset, horizontalAlign, verticalAlign, lineHeight, lineHeightMode, scale, wrap, theme, } = props;
211
+ const { x, y, width, height, padding, value, runs, baseColor, baseFontFamily, baseFontSize, baseBold, baseItalic, baseUnderline, baseStrikethrough, baseBaselineOffset, horizontalAlign, verticalAlign, lineHeight, lineHeightMode, scale, wrap, theme, fontScale = 1, rotation, } = props;
218
212
  const sceneFunc = useCallback((context, _shape) => {
219
213
  const baseResolved = {
220
214
  bold: baseBold,
@@ -238,7 +232,7 @@ export const CellTextRuns = React.memo((props) => {
238
232
  // it walks; the per-segment paint loop below sets it again per
239
233
  // segment so the mutation here is safe.
240
234
  const measureAtom = (atom) => {
241
- const r = resolveSegmentStyle({ text: atom.text, format: atom.format }, baseResolved, theme);
235
+ const r = resolveSegmentStyle({ text: atom.text, format: atom.format }, baseResolved, theme, fontScale);
242
236
  context.setAttr("font", buildFontString(r));
243
237
  return context.measureText(atom.text).width;
244
238
  };
@@ -280,7 +274,7 @@ export const CellTextRuns = React.memo((props) => {
280
274
  // layout: the run font's `getLineAdvance` per line.
281
275
  const resolvedLines = lines.map((lineSegments) => lineSegments.map((seg) => ({
282
276
  seg,
283
- r: resolveSegmentStyle(seg, baseResolved, theme),
277
+ r: resolveSegmentStyle(seg, baseResolved, theme, fontScale),
284
278
  })));
285
279
  const { lineFontSizes, lineHeights, totalHeight: totalH } = computeLineMetrics(resolvedLines, baseResolved, (r) => getLineAdvance(r, lineHeightMode, lineHeight, scale));
286
280
  let topY;
@@ -378,7 +372,8 @@ export const CellTextRuns = React.memo((props) => {
378
372
  height,
379
373
  padding,
380
374
  theme,
375
+ fontScale,
381
376
  ]);
382
- return (React.createElement(Shape, { x: x, y: y, width: width, height: height, sceneFunc: sceneFunc, listening: false, perfectDrawEnabled: false }));
377
+ return (React.createElement(Shape, { x: x, y: y, width: width, height: height, rotation: rotation, sceneFunc: sceneFunc, listening: false, perfectDrawEnabled: false }));
383
378
  });
384
379
  CellTextRuns.displayName = "CellTextRuns";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/cell/index.tsx"],"names":[],"mappings":"AAQA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAsDjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAO3C,eAAO,MAAM,IAAI,oCAAgB,SAAS,uBA6hCxC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/cell/index.tsx"],"names":[],"mappings":"AAQA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAuDjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAO3C,eAAO,MAAM,IAAI,oCAAgB,SAAS,uBAoiCxC,CAAC"}