@effing/canvas 0.24.7 → 0.25.0
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.
- package/dist/index.js +28 -21
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -261,6 +261,12 @@ import { GlobalFonts } from "@napi-rs/canvas";
|
|
|
261
261
|
|
|
262
262
|
// src/jsx/font-metrics.ts
|
|
263
263
|
import { inflateSync } from "zlib";
|
|
264
|
+
function fontMetricsToPx(metrics, fontSize) {
|
|
265
|
+
return {
|
|
266
|
+
ascent: metrics.ascender / metrics.unitsPerEm * fontSize,
|
|
267
|
+
descent: -metrics.descender / metrics.unitsPerEm * fontSize
|
|
268
|
+
};
|
|
269
|
+
}
|
|
264
270
|
var WOFF_SIGNATURE = 2001684038;
|
|
265
271
|
function readWoffTable(view, entry) {
|
|
266
272
|
const compressed = entry.compLength < entry.origLength;
|
|
@@ -474,8 +480,9 @@ function measureTrimMetrics(fontSize, fontFamily, fontWeight, fontStyle, lineHei
|
|
|
474
480
|
let fontAscent;
|
|
475
481
|
let fontDescent;
|
|
476
482
|
if (fontMetrics) {
|
|
477
|
-
|
|
478
|
-
|
|
483
|
+
const px = fontMetricsToPx(fontMetrics, fontSize);
|
|
484
|
+
fontAscent = px.ascent;
|
|
485
|
+
fontDescent = px.descent;
|
|
479
486
|
} else {
|
|
480
487
|
fontAscent = refMetrics.fontBoundingBoxAscent ?? refMetrics.actualBoundingBoxAscent ?? fontSize * 0.8;
|
|
481
488
|
fontDescent = refMetrics.fontBoundingBoxDescent ?? refMetrics.actualBoundingBoxDescent ?? fontSize * 0.2;
|
|
@@ -699,7 +706,8 @@ function layoutText(text, style, maxWidth, ctx, emojiEnabled) {
|
|
|
699
706
|
let totalHeight = 0;
|
|
700
707
|
let maxLineWidth = 0;
|
|
701
708
|
const isAutoLineHeight = style.lineHeight === void 0 || style.lineHeight === "normal";
|
|
702
|
-
|
|
709
|
+
const fontPx = fontMetrics ? fontMetricsToPx(fontMetrics, fontSize) : null;
|
|
710
|
+
let lastPositioningDescent;
|
|
703
711
|
for (let i = 0; i < lines.length; i++) {
|
|
704
712
|
const line = lines[i];
|
|
705
713
|
const lineWidth = measure(line);
|
|
@@ -717,14 +725,16 @@ function layoutText(text, style, maxWidth, ctx, emojiEnabled) {
|
|
|
717
725
|
fontStyle,
|
|
718
726
|
ctx
|
|
719
727
|
);
|
|
720
|
-
|
|
721
|
-
const
|
|
722
|
-
|
|
723
|
-
|
|
728
|
+
const positioningAscent = fontPx?.ascent ?? metrics.ascent;
|
|
729
|
+
const positioningDescent = fontPx?.descent ?? metrics.descent;
|
|
730
|
+
lastPositioningDescent = positioningDescent;
|
|
731
|
+
const contentHeight = positioningAscent + positioningDescent;
|
|
732
|
+
let effectiveAscent = positioningAscent;
|
|
733
|
+
let effectiveDescent = positioningDescent;
|
|
724
734
|
if (isAutoLineHeight && contentHeight > lineHeightPx) {
|
|
725
735
|
const scale = lineHeightPx / contentHeight;
|
|
726
|
-
effectiveAscent =
|
|
727
|
-
effectiveDescent =
|
|
736
|
+
effectiveAscent = positioningAscent * scale;
|
|
737
|
+
effectiveDescent = positioningDescent * scale;
|
|
728
738
|
}
|
|
729
739
|
const baselineY = totalHeight + (lineHeightPx + effectiveAscent - effectiveDescent) / 2;
|
|
730
740
|
segments.push({
|
|
@@ -748,9 +758,9 @@ function layoutText(text, style, maxWidth, ctx, emojiEnabled) {
|
|
|
748
758
|
totalHeight += lineHeightPx;
|
|
749
759
|
maxLineWidth = Math.max(maxLineWidth, lineWidth);
|
|
750
760
|
}
|
|
751
|
-
if (isAutoLineHeight &&
|
|
761
|
+
if (isAutoLineHeight && lastPositioningDescent !== void 0 && segments.length > 0) {
|
|
752
762
|
const lastSeg = segments[segments.length - 1];
|
|
753
|
-
const descentOverflow = lastSeg.y +
|
|
763
|
+
const descentOverflow = lastSeg.y + lastPositioningDescent - totalHeight;
|
|
754
764
|
if (descentOverflow > 0) {
|
|
755
765
|
totalHeight += descentOverflow;
|
|
756
766
|
}
|
|
@@ -788,8 +798,8 @@ function layoutText(text, style, maxWidth, ctx, emojiEnabled) {
|
|
|
788
798
|
function resolveLineHeight(lineHeight, fontSize, canvasMetrics, fontMetrics) {
|
|
789
799
|
if (lineHeight === void 0 || lineHeight === "normal") {
|
|
790
800
|
if (fontMetrics) {
|
|
791
|
-
const
|
|
792
|
-
return
|
|
801
|
+
const px = fontMetricsToPx(fontMetrics, fontSize);
|
|
802
|
+
return px.ascent + px.descent;
|
|
793
803
|
}
|
|
794
804
|
return canvasMetrics ? canvasMetrics.ascent + canvasMetrics.descent : fontSize * 1.2;
|
|
795
805
|
}
|
|
@@ -1207,9 +1217,6 @@ function resolveBoxValue(v, referenceWidth) {
|
|
|
1207
1217
|
function drawRect(ctx, x, y, width, height, style) {
|
|
1208
1218
|
const borderRadius = getBorderRadiusFromStyle(style, width, height);
|
|
1209
1219
|
const hasRoundedCorners = hasRadius(borderRadius);
|
|
1210
|
-
if (style.boxShadow) {
|
|
1211
|
-
drawBoxShadow(ctx, x, y, width, height, style.boxShadow, borderRadius);
|
|
1212
|
-
}
|
|
1213
1220
|
if (style.backgroundColor) {
|
|
1214
1221
|
ctx.fillStyle = style.backgroundColor;
|
|
1215
1222
|
if (hasRoundedCorners) {
|
|
@@ -2831,12 +2838,15 @@ async function drawNodeCore(ctx, node, parentX, parentY, offsetX, offsetY, debug
|
|
|
2831
2838
|
style.transformOrigin
|
|
2832
2839
|
);
|
|
2833
2840
|
}
|
|
2841
|
+
const borderRadius = getBorderRadiusFromStyle(style, width, height);
|
|
2842
|
+
if (style.boxShadow) {
|
|
2843
|
+
drawBoxShadow(ctx, x, y, width, height, style.boxShadow, borderRadius);
|
|
2844
|
+
}
|
|
2834
2845
|
const isClipped = style.overflow === "hidden" || style.overflowX === "hidden" || style.overflowY === "hidden";
|
|
2835
2846
|
if (isClipped) {
|
|
2836
|
-
const borderRadius = getBorderRadiusFromStyle(style, width, height);
|
|
2837
2847
|
applyClip(ctx, x, y, width, height, borderRadius);
|
|
2838
2848
|
}
|
|
2839
|
-
if (style.backgroundColor || style.borderTopWidth || style.borderRightWidth || style.borderBottomWidth || style.borderLeftWidth
|
|
2849
|
+
if (style.backgroundColor || style.borderTopWidth || style.borderRightWidth || style.borderBottomWidth || style.borderLeftWidth) {
|
|
2840
2850
|
drawRect(ctx, x, y, width, height, style);
|
|
2841
2851
|
}
|
|
2842
2852
|
if (style.backgroundImage) {
|
|
@@ -2846,7 +2856,6 @@ async function drawNodeCore(ctx, node, parentX, parentY, offsetX, offsetY, debug
|
|
|
2846
2856
|
const gradient = createGradientFromCSS(ctx, layer, x, y, width, height);
|
|
2847
2857
|
if (gradient) {
|
|
2848
2858
|
ctx.fillStyle = gradient;
|
|
2849
|
-
const borderRadius = getBorderRadiusFromStyle(style, width, height);
|
|
2850
2859
|
if (hasRadius(borderRadius)) {
|
|
2851
2860
|
ctx.beginPath();
|
|
2852
2861
|
roundedRect(
|
|
@@ -2867,7 +2876,6 @@ async function drawNodeCore(ctx, node, parentX, parentY, offsetX, offsetY, debug
|
|
|
2867
2876
|
} else {
|
|
2868
2877
|
const urlMatch = layer.match(/url\(["']?(.*?)["']?\)/);
|
|
2869
2878
|
if (urlMatch) {
|
|
2870
|
-
const borderRadius = getBorderRadiusFromStyle(style, width, height);
|
|
2871
2879
|
if (hasRadius(borderRadius)) {
|
|
2872
2880
|
applyClip(ctx, x, y, width, height, borderRadius);
|
|
2873
2881
|
}
|
|
@@ -2968,7 +2976,6 @@ async function drawNodeCore(ctx, node, parentX, parentY, offsetX, offsetY, debug
|
|
|
2968
2976
|
const imgW = width - paddingLeft - paddingRight - borderLeftW - borderRightW;
|
|
2969
2977
|
const imgH = height - paddingTop - paddingBottom - borderTopW - borderBottomW;
|
|
2970
2978
|
if (!isClipped) {
|
|
2971
|
-
const borderRadius = getBorderRadiusFromStyle(style, width, height);
|
|
2972
2979
|
if (hasRadius(borderRadius)) {
|
|
2973
2980
|
applyClip(ctx, imgX, imgY, imgW, imgH, borderRadius);
|
|
2974
2981
|
}
|