@remotion/web-renderer 4.0.483 → 4.0.485

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.
@@ -1,8 +1,8 @@
1
1
  import type { LinearGradientInfo } from './parse-linear-gradient';
2
2
  export declare const getPrecomposeRectForMask: (element: HTMLElement | SVGElement) => DOMRect;
3
- export declare const handleMask: ({ gradientInfo, rect, precomposeRect, tempContext, scale, }: {
3
+ export declare const handleMask: ({ gradientInfo, maskRect, precomposeRect, tempContext, scale, }: {
4
4
  gradientInfo: LinearGradientInfo;
5
- rect: DOMRect;
5
+ maskRect: DOMRect;
6
6
  precomposeRect: DOMRect;
7
7
  tempContext: OffscreenCanvasRenderingContext2D;
8
8
  scale: number;
@@ -0,0 +1,29 @@
1
+ type TextDecorationLine = 'underline' | 'overline' | 'line-through';
2
+ export type TextDecorationStyle = 'solid' | 'double' | 'dotted' | 'dashed';
3
+ export type TextDecoration = {
4
+ lines: TextDecorationLine[];
5
+ color: string;
6
+ thickness: number;
7
+ style: TextDecorationStyle;
8
+ };
9
+ export declare const parseTextDecoration: ({ onlyBackgroundClipText, style, }: {
10
+ onlyBackgroundClipText: boolean;
11
+ style: CSSStyleDeclaration;
12
+ }) => TextDecoration | null;
13
+ export declare const getTextDecorations: ({ computedStyle, onlyBackgroundClipText, span, }: {
14
+ computedStyle: CSSStyleDeclaration;
15
+ onlyBackgroundClipText: boolean;
16
+ span: HTMLSpanElement;
17
+ }) => TextDecoration[];
18
+ export declare const drawTextDecoration: ({ contextToDraw, fontSizePx, measurements, parentRect, textDecorations, token, y, }: {
19
+ contextToDraw: OffscreenCanvasRenderingContext2D;
20
+ fontSizePx: number;
21
+ measurements: TextMetrics;
22
+ parentRect: DOMRect;
23
+ textDecorations: TextDecoration[];
24
+ token: {
25
+ rect: DOMRect;
26
+ };
27
+ y: number;
28
+ }) => void;
29
+ export {};
@@ -3866,12 +3866,12 @@ var getPrecomposeRectForMask = (element) => {
3866
3866
  };
3867
3867
  var handleMask = ({
3868
3868
  gradientInfo,
3869
- rect,
3869
+ maskRect,
3870
3870
  precomposeRect,
3871
3871
  tempContext,
3872
3872
  scale
3873
3873
  }) => {
3874
- const rectToFill = new DOMRect((rect.left - precomposeRect.left) * scale, (rect.top - precomposeRect.top) * scale, rect.width * scale, rect.height * scale);
3874
+ const rectToFill = new DOMRect((maskRect.left - precomposeRect.left) * scale, (maskRect.top - precomposeRect.top) * scale, maskRect.width * scale, maskRect.height * scale);
3875
3875
  const gradient = createCanvasGradient({
3876
3876
  ctx: tempContext,
3877
3877
  rect: rectToFill,
@@ -3998,7 +3998,7 @@ var processNode = async ({
3998
3998
  if (precompositing.needsMaskImage) {
3999
3999
  handleMask({
4000
4000
  gradientInfo: precompositing.needsMaskImage,
4001
- rect,
4001
+ maskRect: dimensions,
4002
4002
  precomposeRect,
4003
4003
  tempContext,
4004
4004
  scale
@@ -4123,6 +4123,177 @@ var parseTextShadow = (textShadowValue) => {
4123
4123
  return parseShadowValues(textShadowValue);
4124
4124
  };
4125
4125
 
4126
+ // src/drawing/text/text-decoration.ts
4127
+ var textDecorationLines = [
4128
+ "underline",
4129
+ "overline",
4130
+ "line-through"
4131
+ ];
4132
+ var currentColorValues = new Set(["currentcolor", "currentColor"]);
4133
+ var getDefaultTextDecorationThickness = (fontSizePx) => {
4134
+ return Math.max(1, Number.isFinite(fontSizePx) ? fontSizePx / 16 : 1);
4135
+ };
4136
+ var getTextDecorationStyle = (style) => {
4137
+ if (style === "wavy") {
4138
+ return null;
4139
+ }
4140
+ if (style === "double" || style === "dotted" || style === "dashed") {
4141
+ return style;
4142
+ }
4143
+ return "solid";
4144
+ };
4145
+ var parseTextDecoration = ({
4146
+ onlyBackgroundClipText,
4147
+ style
4148
+ }) => {
4149
+ const textDecorationStyle = getTextDecorationStyle(style.getPropertyValue("text-decoration-style").trim());
4150
+ if (textDecorationStyle === null) {
4151
+ return null;
4152
+ }
4153
+ const textDecorationLine = style.getPropertyValue("text-decoration-line");
4154
+ const lineParts = textDecorationLine.split(/\s+/);
4155
+ const lines = textDecorationLines.filter((line) => lineParts.includes(line));
4156
+ if (lines.length === 0) {
4157
+ return null;
4158
+ }
4159
+ const textDecorationThickness = style.getPropertyValue("text-decoration-thickness");
4160
+ const thicknessValue = parseFloat(textDecorationThickness);
4161
+ const thickness = Number.isFinite(thicknessValue) ? thicknessValue : getDefaultTextDecorationThickness(parseFloat(style.fontSize));
4162
+ if (thickness <= 0) {
4163
+ return null;
4164
+ }
4165
+ const textDecorationColor = style.getPropertyValue("text-decoration-color");
4166
+ return {
4167
+ lines,
4168
+ color: onlyBackgroundClipText || !textDecorationColor || currentColorValues.has(textDecorationColor) ? onlyBackgroundClipText ? "black" : style.color : textDecorationColor,
4169
+ thickness,
4170
+ style: textDecorationStyle
4171
+ };
4172
+ };
4173
+ var getTextDecorations = ({
4174
+ computedStyle,
4175
+ onlyBackgroundClipText,
4176
+ span
4177
+ }) => {
4178
+ const decorations = [];
4179
+ const spanDecoration = parseTextDecoration({
4180
+ onlyBackgroundClipText,
4181
+ style: computedStyle
4182
+ });
4183
+ if (spanDecoration) {
4184
+ decorations.push(spanDecoration);
4185
+ }
4186
+ let parent = span.parentElement;
4187
+ while (parent) {
4188
+ const parentDecoration = parseTextDecoration({
4189
+ onlyBackgroundClipText,
4190
+ style: getComputedStyle(parent)
4191
+ });
4192
+ if (parentDecoration) {
4193
+ decorations.push(parentDecoration);
4194
+ }
4195
+ parent = parent.parentElement;
4196
+ }
4197
+ return decorations;
4198
+ };
4199
+ var getTextDecorationY = ({
4200
+ line,
4201
+ measurements,
4202
+ y,
4203
+ thickness,
4204
+ fontSizePx
4205
+ }) => {
4206
+ const fontAscent = measurements.fontBoundingBoxAscent || measurements.actualBoundingBoxAscent || fontSizePx;
4207
+ const fontDescent = measurements.fontBoundingBoxDescent || measurements.actualBoundingBoxDescent || fontSizePx * 0.2;
4208
+ const actualAscent = measurements.actualBoundingBoxAscent || fontAscent;
4209
+ if (line === "underline") {
4210
+ return y + Math.max(thickness, fontDescent * 0.4);
4211
+ }
4212
+ if (line === "overline") {
4213
+ return y - fontAscent + thickness / 2;
4214
+ }
4215
+ return y - actualAscent * 0.35;
4216
+ };
4217
+ var getTextDecorationLineDashPattern = (style, thickness) => {
4218
+ if (style === "dashed") {
4219
+ return [thickness * 2, thickness];
4220
+ }
4221
+ if (style === "dotted") {
4222
+ return [thickness, thickness];
4223
+ }
4224
+ return [];
4225
+ };
4226
+ var strokeTextDecorationLine = ({
4227
+ contextToDraw,
4228
+ endX,
4229
+ lineY,
4230
+ startX
4231
+ }) => {
4232
+ contextToDraw.beginPath();
4233
+ contextToDraw.moveTo(startX, lineY);
4234
+ contextToDraw.lineTo(endX, lineY);
4235
+ contextToDraw.stroke();
4236
+ };
4237
+ var drawTextDecoration = ({
4238
+ contextToDraw,
4239
+ fontSizePx,
4240
+ measurements,
4241
+ parentRect,
4242
+ textDecorations,
4243
+ token,
4244
+ y
4245
+ }) => {
4246
+ if (textDecorations.length === 0) {
4247
+ return;
4248
+ }
4249
+ const startX = token.rect.left - parentRect.x;
4250
+ const endX = token.rect.right - parentRect.x;
4251
+ if (endX <= startX) {
4252
+ return;
4253
+ }
4254
+ contextToDraw.save();
4255
+ contextToDraw.lineCap = "butt";
4256
+ for (const textDecoration of textDecorations) {
4257
+ contextToDraw.strokeStyle = textDecoration.color;
4258
+ contextToDraw.lineWidth = textDecoration.thickness;
4259
+ for (const line of textDecoration.lines) {
4260
+ const lineY = getTextDecorationY({
4261
+ line,
4262
+ measurements,
4263
+ y,
4264
+ thickness: textDecoration.thickness,
4265
+ fontSizePx
4266
+ });
4267
+ if (textDecoration.style === "double") {
4268
+ contextToDraw.setLineDash([]);
4269
+ strokeTextDecorationLine({
4270
+ contextToDraw,
4271
+ endX,
4272
+ lineY: lineY - textDecoration.thickness,
4273
+ startX
4274
+ });
4275
+ strokeTextDecorationLine({
4276
+ contextToDraw,
4277
+ endX,
4278
+ lineY: lineY + textDecoration.thickness,
4279
+ startX
4280
+ });
4281
+ contextToDraw.setLineDash([]);
4282
+ continue;
4283
+ }
4284
+ contextToDraw.setLineDash(getTextDecorationLineDashPattern(textDecoration.style, textDecoration.thickness));
4285
+ strokeTextDecorationLine({
4286
+ contextToDraw,
4287
+ endX,
4288
+ lineY,
4289
+ startX
4290
+ });
4291
+ contextToDraw.setLineDash([]);
4292
+ }
4293
+ }
4294
+ contextToDraw.restore();
4295
+ };
4296
+
4126
4297
  // src/drawing/text/draw-text.ts
4127
4298
  var drawText = ({
4128
4299
  span,
@@ -4174,6 +4345,11 @@ var drawText = ({
4174
4345
  contextToDraw.fillStyle = onlyBackgroundClipText ? "black" : webkitTextFillColor;
4175
4346
  contextToDraw.letterSpacing = letterSpacing;
4176
4347
  contextToDraw.wordSpacing = wordSpacing;
4348
+ const textDecorations = getTextDecorations({
4349
+ computedStyle,
4350
+ onlyBackgroundClipText,
4351
+ span
4352
+ });
4177
4353
  const strokeWidth = parseFloat(webkitTextStrokeWidth);
4178
4354
  const hasStroke = strokeWidth > 0;
4179
4355
  if (hasStroke) {
@@ -4224,6 +4400,15 @@ var drawText = ({
4224
4400
  drawFill();
4225
4401
  drawStroke();
4226
4402
  }
4403
+ drawTextDecoration({
4404
+ contextToDraw,
4405
+ fontSizePx,
4406
+ measurements,
4407
+ parentRect,
4408
+ textDecorations,
4409
+ token,
4410
+ y
4411
+ });
4227
4412
  }
4228
4413
  span.textContent = originalText;
4229
4414
  finishFilter();
@@ -5,7 +5,7 @@ export type WebRendererContainer = 'mp4' | 'webm' | 'mkv' | 'mov' | 'wav' | 'mp3
5
5
  export type WebRendererAudioCodec = 'aac' | 'opus' | 'mp3' | 'vorbis' | 'pcm-s16' | 'flac';
6
6
  export type WebRendererQuality = 'very-low' | 'low' | 'medium' | 'high' | 'very-high';
7
7
  export declare const isAudioOnlyContainer: (container: WebRendererContainer) => boolean;
8
- export declare const codecToMediabunnyCodec: (codec: WebRendererVideoCodec) => "av1" | "avc" | "hevc" | "vp8" | "vp9";
8
+ export declare const codecToMediabunnyCodec: (codec: WebRendererVideoCodec) => "av1" | "avc" | "hevc" | "prores" | "vp8" | "vp9";
9
9
  export declare const containerToMediabunnyContainer: (container: WebRendererContainer) => OutputFormat;
10
10
  export declare const getDefaultVideoCodecForContainer: (container: WebRendererContainer) => WebRendererVideoCodec | null;
11
11
  export declare const getDefaultContainerForCodec: (codec: WebRendererVideoCodec) => WebRendererContainer;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/web-renderer"
4
4
  },
5
5
  "name": "@remotion/web-renderer",
6
- "version": "4.0.483",
6
+ "version": "4.0.485",
7
7
  "main": "dist/index.js",
8
8
  "type": "module",
9
9
  "scripts": {
@@ -17,24 +17,24 @@
17
17
  "remotion": "cd ../example && bunx remotion studio ../web-renderer/src/test/studio.ts --public-dir=../example-videos/videos"
18
18
  },
19
19
  "author": "Remotion <jonny@remotion.dev>",
20
- "license": "UNLICENSED",
20
+ "license": "SEE LICENSE IN LICENSE.md",
21
21
  "dependencies": {
22
- "@mediabunny/mp3-encoder": "1.47.0",
23
- "@mediabunny/aac-encoder": "1.47.0",
24
- "@mediabunny/flac-encoder": "1.47.0",
25
- "@remotion/licensing": "4.0.483",
26
- "remotion": "4.0.483",
27
- "mediabunny": "1.47.0"
22
+ "@mediabunny/mp3-encoder": "1.50.3",
23
+ "@mediabunny/aac-encoder": "1.50.3",
24
+ "@mediabunny/flac-encoder": "1.50.3",
25
+ "@remotion/licensing": "4.0.485",
26
+ "remotion": "4.0.485",
27
+ "mediabunny": "1.50.3"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@react-three/fiber": "9.2.0",
31
- "@remotion/eslint-config-internal": "4.0.483",
32
- "@remotion/paths": "4.0.483",
33
- "@remotion/player": "4.0.483",
34
- "@remotion/media": "4.0.483",
35
- "@remotion/shapes": "4.0.483",
36
- "@remotion/three": "4.0.483",
37
- "@remotion/transitions": "4.0.483",
31
+ "@remotion/eslint-config-internal": "4.0.485",
32
+ "@remotion/paths": "4.0.485",
33
+ "@remotion/player": "4.0.485",
34
+ "@remotion/media": "4.0.485",
35
+ "@remotion/shapes": "4.0.485",
36
+ "@remotion/three": "4.0.485",
37
+ "@remotion/transitions": "4.0.485",
38
38
  "@types/three": "0.170.0",
39
39
  "@typescript/native-preview": "7.0.0-dev.20260217.1",
40
40
  "@vitejs/plugin-react": "4.3.4",