ugcinc-render 1.5.16 → 1.5.18

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.d.mts CHANGED
@@ -1002,6 +1002,10 @@ declare function preloadFonts(): Promise<void>;
1002
1002
  * Check if fonts are loaded
1003
1003
  */
1004
1004
  declare function areFontsLoaded(): boolean;
1005
+ /**
1006
+ * Debug utility to log current font status
1007
+ */
1008
+ declare function debugFontStatus(): void;
1005
1009
 
1006
1010
  /**
1007
1011
  * Fit calculation utilities for media positioning
@@ -1357,4 +1361,4 @@ declare function useResolvedPositions(elements: ImageEditorElement[], textValues
1357
1361
 
1358
1362
  declare const RenderRoot: React.FC;
1359
1363
 
1360
- export { APPLE_EMOJI_FONT, type AudioSegment, type BaseEditorConfig, type BaseSegment, type BorderRadiusConfig, type Channel, type CropAxisConfig, type CropBoundary, type CropBounds, DIMENSION_PRESETS, type DimensionPreset, type DimensionPresetKey, type DynamicCropConfig, type EditorConfig, type EditorSegment, FONT_FAMILIES, FONT_URLS, type FitDimensions, type FitMode, type FontType, type FontWeight, type HorizontalAnchor, type HorizontalSelfAnchor, type Hyphenation, IMAGE_DEFAULTS, ImageEditorComposition, type ImageEditorCompositionProps, type ImageEditorConfig, type ImageEditorElement, type ImageEditorNodeConfig, ImageElement, type ImageElementProps, type ImageSegment, type PictureSegment, type PositionResolutionError, type PositionResolutionResult, type RelativePositionConfigX, type RelativePositionConfigY, RenderRoot, type Segment, type SegmentTimelinePosition, type SegmentType, type StaticSegment, TEXT_DEFAULTS, type TextAlignment, type TextDirection, TextElement, type TextElementProps, type TextOverflow, type TextSegment, type TextWrap, type TimeMode, type TimeValue, VIDEO_DEFAULTS, VISUAL_DEFAULTS, type VerticalAlignment, type VerticalAnchor, type VerticalSelfAnchor, type VideoEditorAudioSegment, type VideoEditorBaseSegment, type VideoEditorChannel, VideoEditorComposition, type VideoEditorCompositionProps, type VideoEditorConfig, type VideoEditorImageSegment, type VideoEditorNodeConfig, type VideoEditorSegment, type VideoEditorTextSegment, type VideoEditorVideoSegment, type VideoEditorVisualSegment, VideoElement, type VideoElementProps, type VideoSegment, type VisualSegment, type VisualSegmentUnion, type WordBreak, applyImageDefaults, applyTextDefaults, applyVideoDefaults, areFontsLoaded, buildFontString, calculateAutoWidthDimensions, calculateCropBounds, calculateEstimatedDuration, calculateFitDimensions, calculateLineWidth, calculateTimelineContentEnd, canSetAsReference, defaultOffset, formatTime, generateOverlayId, generateSegmentId, getBaseSegments, getBorderRadii, getDependentElements, getFontFamily, getOverlays, getReferenceElementX, getReferenceElementY, getSegmentTimelinePosition, hexToRgba, isDynamicCropEnabled, isSegmentVisibleAtTime, parseHexColor, parseTime, preloadFonts, resolveElementPositions, useFontsLoaded, useImageLoader, useImagePreloader, useResolvedPositions, wrapText };
1364
+ export { APPLE_EMOJI_FONT, type AudioSegment, type BaseEditorConfig, type BaseSegment, type BorderRadiusConfig, type Channel, type CropAxisConfig, type CropBoundary, type CropBounds, DIMENSION_PRESETS, type DimensionPreset, type DimensionPresetKey, type DynamicCropConfig, type EditorConfig, type EditorSegment, FONT_FAMILIES, FONT_URLS, type FitDimensions, type FitMode, type FontType, type FontWeight, type HorizontalAnchor, type HorizontalSelfAnchor, type Hyphenation, IMAGE_DEFAULTS, ImageEditorComposition, type ImageEditorCompositionProps, type ImageEditorConfig, type ImageEditorElement, type ImageEditorNodeConfig, ImageElement, type ImageElementProps, type ImageSegment, type PictureSegment, type PositionResolutionError, type PositionResolutionResult, type RelativePositionConfigX, type RelativePositionConfigY, RenderRoot, type Segment, type SegmentTimelinePosition, type SegmentType, type StaticSegment, TEXT_DEFAULTS, type TextAlignment, type TextDirection, TextElement, type TextElementProps, type TextOverflow, type TextSegment, type TextWrap, type TimeMode, type TimeValue, VIDEO_DEFAULTS, VISUAL_DEFAULTS, type VerticalAlignment, type VerticalAnchor, type VerticalSelfAnchor, type VideoEditorAudioSegment, type VideoEditorBaseSegment, type VideoEditorChannel, VideoEditorComposition, type VideoEditorCompositionProps, type VideoEditorConfig, type VideoEditorImageSegment, type VideoEditorNodeConfig, type VideoEditorSegment, type VideoEditorTextSegment, type VideoEditorVideoSegment, type VideoEditorVisualSegment, VideoElement, type VideoElementProps, type VideoSegment, type VisualSegment, type VisualSegmentUnion, type WordBreak, applyImageDefaults, applyTextDefaults, applyVideoDefaults, areFontsLoaded, buildFontString, calculateAutoWidthDimensions, calculateCropBounds, calculateEstimatedDuration, calculateFitDimensions, calculateLineWidth, calculateTimelineContentEnd, canSetAsReference, debugFontStatus, defaultOffset, formatTime, generateOverlayId, generateSegmentId, getBaseSegments, getBorderRadii, getDependentElements, getFontFamily, getOverlays, getReferenceElementX, getReferenceElementY, getSegmentTimelinePosition, hexToRgba, isDynamicCropEnabled, isSegmentVisibleAtTime, parseHexColor, parseTime, preloadFonts, resolveElementPositions, useFontsLoaded, useImageLoader, useImagePreloader, useResolvedPositions, wrapText };
package/dist/index.d.ts CHANGED
@@ -1002,6 +1002,10 @@ declare function preloadFonts(): Promise<void>;
1002
1002
  * Check if fonts are loaded
1003
1003
  */
1004
1004
  declare function areFontsLoaded(): boolean;
1005
+ /**
1006
+ * Debug utility to log current font status
1007
+ */
1008
+ declare function debugFontStatus(): void;
1005
1009
 
1006
1010
  /**
1007
1011
  * Fit calculation utilities for media positioning
@@ -1357,4 +1361,4 @@ declare function useResolvedPositions(elements: ImageEditorElement[], textValues
1357
1361
 
1358
1362
  declare const RenderRoot: React.FC;
1359
1363
 
1360
- export { APPLE_EMOJI_FONT, type AudioSegment, type BaseEditorConfig, type BaseSegment, type BorderRadiusConfig, type Channel, type CropAxisConfig, type CropBoundary, type CropBounds, DIMENSION_PRESETS, type DimensionPreset, type DimensionPresetKey, type DynamicCropConfig, type EditorConfig, type EditorSegment, FONT_FAMILIES, FONT_URLS, type FitDimensions, type FitMode, type FontType, type FontWeight, type HorizontalAnchor, type HorizontalSelfAnchor, type Hyphenation, IMAGE_DEFAULTS, ImageEditorComposition, type ImageEditorCompositionProps, type ImageEditorConfig, type ImageEditorElement, type ImageEditorNodeConfig, ImageElement, type ImageElementProps, type ImageSegment, type PictureSegment, type PositionResolutionError, type PositionResolutionResult, type RelativePositionConfigX, type RelativePositionConfigY, RenderRoot, type Segment, type SegmentTimelinePosition, type SegmentType, type StaticSegment, TEXT_DEFAULTS, type TextAlignment, type TextDirection, TextElement, type TextElementProps, type TextOverflow, type TextSegment, type TextWrap, type TimeMode, type TimeValue, VIDEO_DEFAULTS, VISUAL_DEFAULTS, type VerticalAlignment, type VerticalAnchor, type VerticalSelfAnchor, type VideoEditorAudioSegment, type VideoEditorBaseSegment, type VideoEditorChannel, VideoEditorComposition, type VideoEditorCompositionProps, type VideoEditorConfig, type VideoEditorImageSegment, type VideoEditorNodeConfig, type VideoEditorSegment, type VideoEditorTextSegment, type VideoEditorVideoSegment, type VideoEditorVisualSegment, VideoElement, type VideoElementProps, type VideoSegment, type VisualSegment, type VisualSegmentUnion, type WordBreak, applyImageDefaults, applyTextDefaults, applyVideoDefaults, areFontsLoaded, buildFontString, calculateAutoWidthDimensions, calculateCropBounds, calculateEstimatedDuration, calculateFitDimensions, calculateLineWidth, calculateTimelineContentEnd, canSetAsReference, defaultOffset, formatTime, generateOverlayId, generateSegmentId, getBaseSegments, getBorderRadii, getDependentElements, getFontFamily, getOverlays, getReferenceElementX, getReferenceElementY, getSegmentTimelinePosition, hexToRgba, isDynamicCropEnabled, isSegmentVisibleAtTime, parseHexColor, parseTime, preloadFonts, resolveElementPositions, useFontsLoaded, useImageLoader, useImagePreloader, useResolvedPositions, wrapText };
1364
+ export { APPLE_EMOJI_FONT, type AudioSegment, type BaseEditorConfig, type BaseSegment, type BorderRadiusConfig, type Channel, type CropAxisConfig, type CropBoundary, type CropBounds, DIMENSION_PRESETS, type DimensionPreset, type DimensionPresetKey, type DynamicCropConfig, type EditorConfig, type EditorSegment, FONT_FAMILIES, FONT_URLS, type FitDimensions, type FitMode, type FontType, type FontWeight, type HorizontalAnchor, type HorizontalSelfAnchor, type Hyphenation, IMAGE_DEFAULTS, ImageEditorComposition, type ImageEditorCompositionProps, type ImageEditorConfig, type ImageEditorElement, type ImageEditorNodeConfig, ImageElement, type ImageElementProps, type ImageSegment, type PictureSegment, type PositionResolutionError, type PositionResolutionResult, type RelativePositionConfigX, type RelativePositionConfigY, RenderRoot, type Segment, type SegmentTimelinePosition, type SegmentType, type StaticSegment, TEXT_DEFAULTS, type TextAlignment, type TextDirection, TextElement, type TextElementProps, type TextOverflow, type TextSegment, type TextWrap, type TimeMode, type TimeValue, VIDEO_DEFAULTS, VISUAL_DEFAULTS, type VerticalAlignment, type VerticalAnchor, type VerticalSelfAnchor, type VideoEditorAudioSegment, type VideoEditorBaseSegment, type VideoEditorChannel, VideoEditorComposition, type VideoEditorCompositionProps, type VideoEditorConfig, type VideoEditorImageSegment, type VideoEditorNodeConfig, type VideoEditorSegment, type VideoEditorTextSegment, type VideoEditorVideoSegment, type VideoEditorVisualSegment, VideoElement, type VideoElementProps, type VideoSegment, type VisualSegment, type VisualSegmentUnion, type WordBreak, applyImageDefaults, applyTextDefaults, applyVideoDefaults, areFontsLoaded, buildFontString, calculateAutoWidthDimensions, calculateCropBounds, calculateEstimatedDuration, calculateFitDimensions, calculateLineWidth, calculateTimelineContentEnd, canSetAsReference, debugFontStatus, defaultOffset, formatTime, generateOverlayId, generateSegmentId, getBaseSegments, getBorderRadii, getDependentElements, getFontFamily, getOverlays, getReferenceElementX, getReferenceElementY, getSegmentTimelinePosition, hexToRgba, isDynamicCropEnabled, isSegmentVisibleAtTime, parseHexColor, parseTime, preloadFonts, resolveElementPositions, useFontsLoaded, useImageLoader, useImagePreloader, useResolvedPositions, wrapText };
package/dist/index.js CHANGED
@@ -56,6 +56,7 @@ __export(index_exports, {
56
56
  calculateLineWidth: () => calculateLineWidth,
57
57
  calculateTimelineContentEnd: () => calculateTimelineContentEnd,
58
58
  canSetAsReference: () => canSetAsReference,
59
+ debugFontStatus: () => debugFontStatus,
59
60
  defaultOffset: () => defaultOffset,
60
61
  formatTime: () => formatTime,
61
62
  generateOverlayId: () => generateOverlayId,
@@ -190,43 +191,117 @@ var FONT_URLS = {
190
191
  }
191
192
  };
192
193
  async function preloadFonts() {
194
+ console.log("[ugcinc-render/fonts] preloadFonts() called");
193
195
  if (typeof document !== "undefined") {
194
- const fontPromises = [];
195
- const tiktokRegular = new FontFace(
196
- "TikTok Sans",
197
- `url(${FONT_URLS.tiktok.regular})`,
198
- { weight: "normal" }
199
- );
200
- fontPromises.push(tiktokRegular.load());
201
- const tiktokBold = new FontFace(
202
- "TikTok Sans",
203
- `url(${FONT_URLS.tiktok.bold})`,
204
- { weight: "bold" }
205
- );
206
- fontPromises.push(tiktokBold.load());
207
- const sfPro = new FontFace(
208
- "SF Pro",
209
- `url(${FONT_URLS.apple.regular})`,
210
- { weight: "normal" }
211
- );
212
- fontPromises.push(sfPro.load());
213
- const appleEmoji = new FontFace(
214
- "Apple Color Emoji",
215
- `url(${FONT_URLS.emoji.apple})`,
216
- { weight: "normal" }
217
- );
218
- fontPromises.push(appleEmoji.load());
219
- const loadedFonts = await Promise.all(fontPromises);
220
- loadedFonts.forEach((font) => {
221
- document.fonts.add(font);
196
+ console.log("[ugcinc-render/fonts] Browser environment detected, loading fonts...");
197
+ const fontResults = [];
198
+ try {
199
+ const tiktokRegular = new FontFace(
200
+ "TikTok Sans",
201
+ `url(${FONT_URLS.tiktok.regular})`,
202
+ { weight: "normal" }
203
+ );
204
+ console.log(`[ugcinc-render/fonts] Loading TikTok Sans Regular from: ${FONT_URLS.tiktok.regular}`);
205
+ await tiktokRegular.load();
206
+ document.fonts.add(tiktokRegular);
207
+ fontResults.push({ name: "TikTok Sans Regular", status: "success" });
208
+ } catch (err) {
209
+ const errorMsg = err instanceof Error ? err.message : String(err);
210
+ console.error(`[ugcinc-render/fonts] Failed to load TikTok Sans Regular:`, errorMsg);
211
+ fontResults.push({ name: "TikTok Sans Regular", status: "error", error: errorMsg });
212
+ }
213
+ try {
214
+ const tiktokBold = new FontFace(
215
+ "TikTok Sans",
216
+ `url(${FONT_URLS.tiktok.bold})`,
217
+ { weight: "bold" }
218
+ );
219
+ console.log(`[ugcinc-render/fonts] Loading TikTok Sans Bold from: ${FONT_URLS.tiktok.bold}`);
220
+ await tiktokBold.load();
221
+ document.fonts.add(tiktokBold);
222
+ fontResults.push({ name: "TikTok Sans Bold", status: "success" });
223
+ } catch (err) {
224
+ const errorMsg = err instanceof Error ? err.message : String(err);
225
+ console.error(`[ugcinc-render/fonts] Failed to load TikTok Sans Bold:`, errorMsg);
226
+ fontResults.push({ name: "TikTok Sans Bold", status: "error", error: errorMsg });
227
+ }
228
+ try {
229
+ const sfPro = new FontFace(
230
+ "SF Pro",
231
+ `url(${FONT_URLS.apple.regular})`,
232
+ { weight: "normal" }
233
+ );
234
+ console.log(`[ugcinc-render/fonts] Loading SF Pro from: ${FONT_URLS.apple.regular}`);
235
+ await sfPro.load();
236
+ document.fonts.add(sfPro);
237
+ fontResults.push({ name: "SF Pro", status: "success" });
238
+ } catch (err) {
239
+ const errorMsg = err instanceof Error ? err.message : String(err);
240
+ console.error(`[ugcinc-render/fonts] Failed to load SF Pro:`, errorMsg);
241
+ fontResults.push({ name: "SF Pro", status: "error", error: errorMsg });
242
+ }
243
+ try {
244
+ const appleEmoji = new FontFace(
245
+ "Apple Color Emoji",
246
+ `url(${FONT_URLS.emoji.apple})`,
247
+ { weight: "normal" }
248
+ );
249
+ console.log(`[ugcinc-render/fonts] Loading Apple Color Emoji from: ${FONT_URLS.emoji.apple}`);
250
+ await appleEmoji.load();
251
+ document.fonts.add(appleEmoji);
252
+ fontResults.push({ name: "Apple Color Emoji", status: "success" });
253
+ } catch (err) {
254
+ const errorMsg = err instanceof Error ? err.message : String(err);
255
+ console.error(`[ugcinc-render/fonts] Failed to load Apple Color Emoji:`, errorMsg);
256
+ fontResults.push({ name: "Apple Color Emoji", status: "error", error: errorMsg });
257
+ }
258
+ console.log("[ugcinc-render/fonts] Font loading complete. Results:", fontResults);
259
+ const availableFonts = [];
260
+ document.fonts.forEach((font) => {
261
+ availableFonts.push(`${font.family} (${font.weight}, ${font.status})`);
222
262
  });
263
+ console.log("[ugcinc-render/fonts] Available fonts in document:", availableFonts);
264
+ } else {
265
+ console.log("[ugcinc-render/fonts] Not in browser environment, skipping font loading");
223
266
  }
224
267
  }
225
268
  function areFontsLoaded() {
226
269
  if (typeof document === "undefined") {
270
+ console.log("[ugcinc-render/fonts] areFontsLoaded: Not in browser environment");
227
271
  return false;
228
272
  }
229
- return document.fonts.check('normal 16px "TikTok Sans"') && document.fonts.check('bold 16px "TikTok Sans"') && document.fonts.check('normal 16px "SF Pro"') && document.fonts.check('normal 16px "Apple Color Emoji"');
273
+ const tiktokRegular = document.fonts.check('normal 16px "TikTok Sans"');
274
+ const tiktokBold = document.fonts.check('bold 16px "TikTok Sans"');
275
+ const sfPro = document.fonts.check('normal 16px "SF Pro"');
276
+ const appleEmoji = document.fonts.check('normal 16px "Apple Color Emoji"');
277
+ console.log("[ugcinc-render/fonts] areFontsLoaded check:", {
278
+ tiktokRegular,
279
+ tiktokBold,
280
+ sfPro,
281
+ appleEmoji
282
+ });
283
+ return tiktokRegular && tiktokBold && sfPro && appleEmoji;
284
+ }
285
+ function debugFontStatus() {
286
+ console.log("[ugcinc-render/fonts] === FONT DEBUG STATUS ===");
287
+ if (typeof document === "undefined") {
288
+ console.log("[ugcinc-render/fonts] Not in browser environment");
289
+ return;
290
+ }
291
+ console.log("[ugcinc-render/fonts] Font checks:");
292
+ console.log(" - TikTok Sans (normal):", document.fonts.check('normal 16px "TikTok Sans"'));
293
+ console.log(" - TikTok Sans (bold):", document.fonts.check('bold 16px "TikTok Sans"'));
294
+ console.log(" - SF Pro:", document.fonts.check('normal 16px "SF Pro"'));
295
+ console.log(" - Apple Color Emoji:", document.fonts.check('normal 16px "Apple Color Emoji"'));
296
+ console.log("[ugcinc-render/fonts] All fonts in document.fonts:");
297
+ document.fonts.forEach((font) => {
298
+ console.log(` - ${font.family}: weight=${font.weight}, style=${font.style}, status=${font.status}`);
299
+ });
300
+ console.log("[ugcinc-render/fonts] Font family stacks:");
301
+ console.log(" - tiktok:", FONT_FAMILIES.tiktok);
302
+ console.log(" - apple:", FONT_FAMILIES.apple);
303
+ console.log(" - arial:", FONT_FAMILIES.arial);
304
+ console.log("[ugcinc-render/fonts] === END FONT DEBUG ===");
230
305
  }
231
306
 
232
307
  // src/utils/text.ts
@@ -326,15 +401,48 @@ function calculateAutoWidthAndLines({
326
401
  letterSpacing,
327
402
  lineHeight
328
403
  }) {
404
+ console.log("[TextElement/calculateAutoWidthAndLines] ===== START CALCULATION =====");
405
+ console.log("[TextElement/calculateAutoWidthAndLines] Input params:", {
406
+ text: text.substring(0, 100) + (text.length > 100 ? "..." : ""),
407
+ textLength: text.length,
408
+ maxWidth,
409
+ paddingLeft,
410
+ paddingRight,
411
+ fontSize,
412
+ fontWeight,
413
+ fontFamily,
414
+ letterSpacing,
415
+ lineHeight
416
+ });
329
417
  if (typeof document === "undefined") {
418
+ console.log("[TextElement/calculateAutoWidthAndLines] SSR mode - returning maxWidth");
330
419
  return { width: maxWidth, lines: [text] };
331
420
  }
421
+ if (typeof document.fonts !== "undefined") {
422
+ const fontChecks = {
423
+ "SF Pro normal": document.fonts.check(`normal ${fontSize}px "SF Pro"`),
424
+ "SF Pro bold": document.fonts.check(`bold ${fontSize}px "SF Pro"`),
425
+ "TikTok Sans normal": document.fonts.check(`normal ${fontSize}px "TikTok Sans"`),
426
+ "TikTok Sans bold": document.fonts.check(`bold ${fontSize}px "TikTok Sans"`),
427
+ "requestedFont": document.fonts.check(`${fontWeight} ${fontSize}px ${fontFamily.split(",")[0]}`)
428
+ };
429
+ console.log("[TextElement/calculateAutoWidthAndLines] Font loading status:", fontChecks);
430
+ const loadedFonts = [];
431
+ document.fonts.forEach((font) => {
432
+ loadedFonts.push(`${font.family} (weight: ${font.weight}, status: ${font.status})`);
433
+ });
434
+ console.log("[TextElement/calculateAutoWidthAndLines] All document.fonts:", loadedFonts);
435
+ } else {
436
+ console.log("[TextElement/calculateAutoWidthAndLines] document.fonts API not available");
437
+ }
332
438
  const availableWidth = maxWidth - paddingLeft - paddingRight;
439
+ console.log("[TextElement/calculateAutoWidthAndLines] Available width for text:", availableWidth);
333
440
  if (availableWidth <= 0) {
441
+ console.log("[TextElement/calculateAutoWidthAndLines] Available width <= 0, returning maxWidth");
334
442
  return { width: maxWidth, lines: [text] };
335
443
  }
336
444
  const measureSpan = document.createElement("span");
337
- measureSpan.style.cssText = `
445
+ const cssText = `
338
446
  position: absolute;
339
447
  visibility: hidden;
340
448
  pointer-events: none;
@@ -344,16 +452,29 @@ function calculateAutoWidthAndLines({
344
452
  letter-spacing: ${letterSpacing}px;
345
453
  white-space: nowrap;
346
454
  `;
455
+ measureSpan.style.cssText = cssText;
456
+ console.log("[TextElement/calculateAutoWidthAndLines] Measurement span CSS:", cssText.replace(/\s+/g, " ").trim());
347
457
  document.body.appendChild(measureSpan);
348
458
  const measureText = (textToMeasure) => {
349
459
  measureSpan.textContent = textToMeasure;
350
- return measureSpan.getBoundingClientRect().width;
460
+ const width = measureSpan.getBoundingClientRect().width;
461
+ return width;
351
462
  };
352
463
  measureSpan.textContent = "M";
353
464
  const charWidth = measureSpan.getBoundingClientRect().width;
465
+ console.log('[TextElement/calculateAutoWidthAndLines] Single "M" character width:', charWidth);
466
+ measureSpan.textContent = "Test String";
467
+ const testStringWidth = measureSpan.getBoundingClientRect().width;
468
+ console.log('[TextElement/calculateAutoWidthAndLines] "Test String" width:', testStringWidth);
469
+ const computedStyle = window.getComputedStyle(measureSpan);
470
+ console.log("[TextElement/calculateAutoWidthAndLines] Computed font-family:", computedStyle.fontFamily);
471
+ console.log("[TextElement/calculateAutoWidthAndLines] Computed font-size:", computedStyle.fontSize);
472
+ console.log("[TextElement/calculateAutoWidthAndLines] Computed font-weight:", computedStyle.fontWeight);
473
+ console.log("[TextElement/calculateAutoWidthAndLines] Computed letter-spacing:", computedStyle.letterSpacing);
354
474
  const words = text.split(/(\s+)/);
355
475
  const lines = [];
356
476
  let currentLine = "";
477
+ console.log("[TextElement/calculateAutoWidthAndLines] Word count:", words.filter((w) => w.trim()).length);
357
478
  for (let i = 0; i < words.length; i++) {
358
479
  const word = words[i];
359
480
  if (word === "\n" || word === "\r\n") {
@@ -409,15 +530,60 @@ function calculateAutoWidthAndLines({
409
530
  lines.push("");
410
531
  }
411
532
  let widestLineWidth = 0;
533
+ const lineWidths = [];
412
534
  for (const line of lines) {
413
535
  const lineWidth = measureText(line);
536
+ lineWidths.push({ line: line.substring(0, 50) + (line.length > 50 ? "..." : ""), width: lineWidth });
414
537
  widestLineWidth = Math.max(widestLineWidth, lineWidth);
415
538
  }
539
+ console.log("[TextElement/calculateAutoWidthAndLines] Line measurements:", lineWidths);
540
+ console.log("[TextElement/calculateAutoWidthAndLines] Widest line width:", widestLineWidth);
416
541
  document.body.removeChild(measureSpan);
417
542
  const calculatedWidth = Math.min(widestLineWidth + paddingLeft + paddingRight, maxWidth);
543
+ console.log("[TextElement/calculateAutoWidthAndLines] Final calculation:", {
544
+ widestLineWidth,
545
+ paddingLeft,
546
+ paddingRight,
547
+ rawCalculatedWidth: widestLineWidth + paddingLeft + paddingRight,
548
+ cappedToMaxWidth: calculatedWidth,
549
+ maxWidth
550
+ });
551
+ console.log("[TextElement/calculateAutoWidthAndLines] ===== END CALCULATION =====");
418
552
  return { width: calculatedWidth, lines };
419
553
  }
420
554
  function TextElement({ segment, scale = 1 }) {
555
+ import_react.default.useEffect(() => {
556
+ const fontFamily2 = getFontFamily(segment.fontType ?? TEXT_DEFAULTS.fontType);
557
+ console.log("[TextElement] ===== RENDER EFFECT =====");
558
+ console.log("[TextElement] Segment ID:", segment.id);
559
+ console.log("[TextElement] Rendering with:", {
560
+ text: segment.text?.substring(0, 50) + (segment.text?.length > 50 ? "..." : ""),
561
+ fontType: segment.fontType ?? TEXT_DEFAULTS.fontType,
562
+ fontFamily: fontFamily2,
563
+ hasEmojis: /[\u{1F300}-\u{1F9FF}]/u.test(segment.text || ""),
564
+ autoWidth: segment.autoWidth,
565
+ boxAlign: segment.boxAlign
566
+ });
567
+ console.log("[TextElement] Segment dimensions:", {
568
+ xOffset: segment.xOffset,
569
+ yOffset: segment.yOffset,
570
+ width: segment.width,
571
+ height: segment.height
572
+ });
573
+ console.log("[TextElement] Segment padding:", {
574
+ paddingTop: segment.paddingTop,
575
+ paddingRight: segment.paddingRight,
576
+ paddingBottom: segment.paddingBottom,
577
+ paddingLeft: segment.paddingLeft
578
+ });
579
+ console.log("[TextElement] Segment font styling:", {
580
+ fontSize: segment.fontSize,
581
+ fontWeight: segment.fontWeight,
582
+ letterSpacing: segment.letterSpacing,
583
+ lineHeight: segment.lineHeight
584
+ });
585
+ console.log("[TextElement] Scale:", scale);
586
+ }, [segment, scale]);
421
587
  const fontType = segment.fontType ?? TEXT_DEFAULTS.fontType;
422
588
  const fontSize = (segment.fontSize ?? TEXT_DEFAULTS.fontSize) * scale;
423
589
  const fontWeight = segment.fontWeight ?? TEXT_DEFAULTS.fontWeight;
@@ -496,7 +662,7 @@ function TextElement({ segment, scale = 1 }) {
496
662
  lineHeight
497
663
  });
498
664
  }
499
- return {
665
+ const result = {
500
666
  calculatedWidth: autoWidth ? finalResult.width : width,
501
667
  calculatedLines: autoWidth ? finalResult.lines : [segment.text],
502
668
  paddingTop: finalPaddingTop,
@@ -504,6 +670,19 @@ function TextElement({ segment, scale = 1 }) {
504
670
  paddingBottom: finalPaddingBottom,
505
671
  paddingLeft: finalPaddingLeft
506
672
  };
673
+ console.log("[TextElement/useMemo] ===== FINAL VALUES =====");
674
+ console.log("[TextElement/useMemo] autoWidth:", autoWidth);
675
+ console.log("[TextElement/useMemo] calculatedWidth:", result.calculatedWidth);
676
+ console.log("[TextElement/useMemo] calculatedLines:", result.calculatedLines);
677
+ console.log("[TextElement/useMemo] Final padding:", {
678
+ top: result.paddingTop,
679
+ right: result.paddingRight,
680
+ bottom: result.paddingBottom,
681
+ left: result.paddingLeft
682
+ });
683
+ console.log("[TextElement/useMemo] Element width (maxWidth):", width);
684
+ console.log("[TextElement/useMemo] Difference (maxWidth - calculatedWidth):", width - result.calculatedWidth);
685
+ return result;
507
686
  }, [
508
687
  autoWidth,
509
688
  segment.text,
@@ -618,11 +797,29 @@ function TextElement({ segment, scale = 1 }) {
618
797
  verticalAlign
619
798
  ]);
620
799
  if (autoWidth) {
800
+ console.log("[TextElement/render] ===== RENDERING WITH AUTO-WIDTH =====");
801
+ console.log("[TextElement/render] Segment ID:", segment.id);
802
+ console.log("[TextElement/render] calculatedWidth being applied:", calculatedWidth);
803
+ console.log("[TextElement/render] maxWidth (element width):", width);
804
+ console.log("[TextElement/render] boxAlign:", boxAlign);
805
+ console.log("[TextElement/render] textAlign:", alignment);
806
+ console.log("[TextElement/render] Number of lines:", calculatedLines.length);
807
+ console.log("[TextElement/render] textStyle padding:", textStyle.padding);
808
+ console.log("[TextElement/render] textStyle fontFamily:", textStyle.fontFamily);
809
+ console.log("[TextElement/render] textStyle fontSize:", textStyle.fontSize);
810
+ console.log("[TextElement/render] textStyle letterSpacing:", textStyle.letterSpacing);
621
811
  const textContent = calculatedLines.map((line, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.default.Fragment, { children: [
622
812
  line,
623
813
  index < calculatedLines.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {})
624
814
  ] }, index));
625
815
  if (backgroundColor) {
816
+ console.log("[TextElement/render] Rendering WITH background");
817
+ console.log("[TextElement/render] Background wrapper style:", {
818
+ width: calculatedWidth,
819
+ maxWidth: width,
820
+ backgroundColor: hexToRgba(backgroundColor, backgroundOpacity),
821
+ borderRadius: borderRadiusStyle
822
+ });
626
823
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: positioningContainerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
627
824
  "div",
628
825
  {
@@ -636,6 +833,7 @@ function TextElement({ segment, scale = 1 }) {
636
833
  }
637
834
  ) });
638
835
  }
836
+ console.log("[TextElement/render] Rendering WITHOUT background");
639
837
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: positioningContainerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { width: calculatedWidth, maxWidth: width }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: textStyle, children: textContent }) }) });
640
838
  }
641
839
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: positioningContainerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: backgroundBoxStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: textStyle, children: segment.text }) }) });
@@ -1158,7 +1356,7 @@ function getSortedSegments(config) {
1158
1356
  });
1159
1357
  }
1160
1358
  function elementToTextSegment(elem) {
1161
- return {
1359
+ const segment = {
1162
1360
  id: elem.id,
1163
1361
  type: "text",
1164
1362
  source: "",
@@ -1196,6 +1394,27 @@ function elementToTextSegment(elem) {
1196
1394
  autoWidth: elem.autoWidth,
1197
1395
  boxAlign: elem.boxAlign
1198
1396
  };
1397
+ console.log("[ImageEditorComposition/elementToTextSegment] ===== CONVERTING ELEMENT TO SEGMENT =====");
1398
+ console.log("[ImageEditorComposition/elementToTextSegment] Element ID:", elem.id);
1399
+ console.log("[ImageEditorComposition/elementToTextSegment] Element text:", (elem.text ?? "").substring(0, 50));
1400
+ console.log("[ImageEditorComposition/elementToTextSegment] Element dimensions:", { x: elem.x, y: elem.y, width: elem.width, height: elem.height });
1401
+ console.log("[ImageEditorComposition/elementToTextSegment] Element padding:", {
1402
+ paddingTop: elem.paddingTop,
1403
+ paddingRight: elem.paddingRight,
1404
+ paddingBottom: elem.paddingBottom,
1405
+ paddingLeft: elem.paddingLeft
1406
+ });
1407
+ console.log("[ImageEditorComposition/elementToTextSegment] Element autoWidth:", elem.autoWidth, "boxAlign:", elem.boxAlign);
1408
+ console.log("[ImageEditorComposition/elementToTextSegment] Element font:", elem.font, "fontSize:", elem.fontSize, "fontWeight:", elem.fontWeight);
1409
+ console.log("[ImageEditorComposition/elementToTextSegment] Element letterSpacing:", elem.letterSpacing, "lineHeight:", elem.lineHeight);
1410
+ console.log("[ImageEditorComposition/elementToTextSegment] Segment created:", {
1411
+ fontType: segment.fontType,
1412
+ fontSize: segment.fontSize,
1413
+ fontWeight: segment.fontWeight,
1414
+ letterSpacing: segment.letterSpacing,
1415
+ lineHeight: segment.lineHeight
1416
+ });
1417
+ return segment;
1199
1418
  }
1200
1419
  function elementToImageSegment(elem, source) {
1201
1420
  return {
@@ -1231,8 +1450,20 @@ function ImageEditorComposition({
1231
1450
  textValues = {},
1232
1451
  dynamicCrop
1233
1452
  }) {
1453
+ console.log("[ImageEditorComposition] ===== COMPOSITION RENDER =====");
1454
+ console.log("[ImageEditorComposition] Props received:", {
1455
+ hasConfig: !!config,
1456
+ hasElements: !!elements,
1457
+ elementCount: elements?.length ?? 0,
1458
+ width,
1459
+ height,
1460
+ scale,
1461
+ backgroundType,
1462
+ textValuesKeys: Object.keys(textValues)
1463
+ });
1234
1464
  const canvasWidth = width ?? config?.width ?? 1080;
1235
1465
  const canvasHeight = height ?? config?.height ?? 1920;
1466
+ console.log("[ImageEditorComposition] Canvas dimensions:", { canvasWidth, canvasHeight });
1236
1467
  const resolvedElements = (0, import_react3.useMemo)(() => {
1237
1468
  if (!elements) return null;
1238
1469
  const result = resolveElementPositions(elements, textValues);
@@ -1958,6 +2189,7 @@ var RenderRoot = () => {
1958
2189
  calculateLineWidth,
1959
2190
  calculateTimelineContentEnd,
1960
2191
  canSetAsReference,
2192
+ debugFontStatus,
1961
2193
  defaultOffset,
1962
2194
  formatTime,
1963
2195
  generateOverlayId,
package/dist/index.mjs CHANGED
@@ -105,43 +105,117 @@ var FONT_URLS = {
105
105
  }
106
106
  };
107
107
  async function preloadFonts() {
108
+ console.log("[ugcinc-render/fonts] preloadFonts() called");
108
109
  if (typeof document !== "undefined") {
109
- const fontPromises = [];
110
- const tiktokRegular = new FontFace(
111
- "TikTok Sans",
112
- `url(${FONT_URLS.tiktok.regular})`,
113
- { weight: "normal" }
114
- );
115
- fontPromises.push(tiktokRegular.load());
116
- const tiktokBold = new FontFace(
117
- "TikTok Sans",
118
- `url(${FONT_URLS.tiktok.bold})`,
119
- { weight: "bold" }
120
- );
121
- fontPromises.push(tiktokBold.load());
122
- const sfPro = new FontFace(
123
- "SF Pro",
124
- `url(${FONT_URLS.apple.regular})`,
125
- { weight: "normal" }
126
- );
127
- fontPromises.push(sfPro.load());
128
- const appleEmoji = new FontFace(
129
- "Apple Color Emoji",
130
- `url(${FONT_URLS.emoji.apple})`,
131
- { weight: "normal" }
132
- );
133
- fontPromises.push(appleEmoji.load());
134
- const loadedFonts = await Promise.all(fontPromises);
135
- loadedFonts.forEach((font) => {
136
- document.fonts.add(font);
110
+ console.log("[ugcinc-render/fonts] Browser environment detected, loading fonts...");
111
+ const fontResults = [];
112
+ try {
113
+ const tiktokRegular = new FontFace(
114
+ "TikTok Sans",
115
+ `url(${FONT_URLS.tiktok.regular})`,
116
+ { weight: "normal" }
117
+ );
118
+ console.log(`[ugcinc-render/fonts] Loading TikTok Sans Regular from: ${FONT_URLS.tiktok.regular}`);
119
+ await tiktokRegular.load();
120
+ document.fonts.add(tiktokRegular);
121
+ fontResults.push({ name: "TikTok Sans Regular", status: "success" });
122
+ } catch (err) {
123
+ const errorMsg = err instanceof Error ? err.message : String(err);
124
+ console.error(`[ugcinc-render/fonts] Failed to load TikTok Sans Regular:`, errorMsg);
125
+ fontResults.push({ name: "TikTok Sans Regular", status: "error", error: errorMsg });
126
+ }
127
+ try {
128
+ const tiktokBold = new FontFace(
129
+ "TikTok Sans",
130
+ `url(${FONT_URLS.tiktok.bold})`,
131
+ { weight: "bold" }
132
+ );
133
+ console.log(`[ugcinc-render/fonts] Loading TikTok Sans Bold from: ${FONT_URLS.tiktok.bold}`);
134
+ await tiktokBold.load();
135
+ document.fonts.add(tiktokBold);
136
+ fontResults.push({ name: "TikTok Sans Bold", status: "success" });
137
+ } catch (err) {
138
+ const errorMsg = err instanceof Error ? err.message : String(err);
139
+ console.error(`[ugcinc-render/fonts] Failed to load TikTok Sans Bold:`, errorMsg);
140
+ fontResults.push({ name: "TikTok Sans Bold", status: "error", error: errorMsg });
141
+ }
142
+ try {
143
+ const sfPro = new FontFace(
144
+ "SF Pro",
145
+ `url(${FONT_URLS.apple.regular})`,
146
+ { weight: "normal" }
147
+ );
148
+ console.log(`[ugcinc-render/fonts] Loading SF Pro from: ${FONT_URLS.apple.regular}`);
149
+ await sfPro.load();
150
+ document.fonts.add(sfPro);
151
+ fontResults.push({ name: "SF Pro", status: "success" });
152
+ } catch (err) {
153
+ const errorMsg = err instanceof Error ? err.message : String(err);
154
+ console.error(`[ugcinc-render/fonts] Failed to load SF Pro:`, errorMsg);
155
+ fontResults.push({ name: "SF Pro", status: "error", error: errorMsg });
156
+ }
157
+ try {
158
+ const appleEmoji = new FontFace(
159
+ "Apple Color Emoji",
160
+ `url(${FONT_URLS.emoji.apple})`,
161
+ { weight: "normal" }
162
+ );
163
+ console.log(`[ugcinc-render/fonts] Loading Apple Color Emoji from: ${FONT_URLS.emoji.apple}`);
164
+ await appleEmoji.load();
165
+ document.fonts.add(appleEmoji);
166
+ fontResults.push({ name: "Apple Color Emoji", status: "success" });
167
+ } catch (err) {
168
+ const errorMsg = err instanceof Error ? err.message : String(err);
169
+ console.error(`[ugcinc-render/fonts] Failed to load Apple Color Emoji:`, errorMsg);
170
+ fontResults.push({ name: "Apple Color Emoji", status: "error", error: errorMsg });
171
+ }
172
+ console.log("[ugcinc-render/fonts] Font loading complete. Results:", fontResults);
173
+ const availableFonts = [];
174
+ document.fonts.forEach((font) => {
175
+ availableFonts.push(`${font.family} (${font.weight}, ${font.status})`);
137
176
  });
177
+ console.log("[ugcinc-render/fonts] Available fonts in document:", availableFonts);
178
+ } else {
179
+ console.log("[ugcinc-render/fonts] Not in browser environment, skipping font loading");
138
180
  }
139
181
  }
140
182
  function areFontsLoaded() {
141
183
  if (typeof document === "undefined") {
184
+ console.log("[ugcinc-render/fonts] areFontsLoaded: Not in browser environment");
142
185
  return false;
143
186
  }
144
- return document.fonts.check('normal 16px "TikTok Sans"') && document.fonts.check('bold 16px "TikTok Sans"') && document.fonts.check('normal 16px "SF Pro"') && document.fonts.check('normal 16px "Apple Color Emoji"');
187
+ const tiktokRegular = document.fonts.check('normal 16px "TikTok Sans"');
188
+ const tiktokBold = document.fonts.check('bold 16px "TikTok Sans"');
189
+ const sfPro = document.fonts.check('normal 16px "SF Pro"');
190
+ const appleEmoji = document.fonts.check('normal 16px "Apple Color Emoji"');
191
+ console.log("[ugcinc-render/fonts] areFontsLoaded check:", {
192
+ tiktokRegular,
193
+ tiktokBold,
194
+ sfPro,
195
+ appleEmoji
196
+ });
197
+ return tiktokRegular && tiktokBold && sfPro && appleEmoji;
198
+ }
199
+ function debugFontStatus() {
200
+ console.log("[ugcinc-render/fonts] === FONT DEBUG STATUS ===");
201
+ if (typeof document === "undefined") {
202
+ console.log("[ugcinc-render/fonts] Not in browser environment");
203
+ return;
204
+ }
205
+ console.log("[ugcinc-render/fonts] Font checks:");
206
+ console.log(" - TikTok Sans (normal):", document.fonts.check('normal 16px "TikTok Sans"'));
207
+ console.log(" - TikTok Sans (bold):", document.fonts.check('bold 16px "TikTok Sans"'));
208
+ console.log(" - SF Pro:", document.fonts.check('normal 16px "SF Pro"'));
209
+ console.log(" - Apple Color Emoji:", document.fonts.check('normal 16px "Apple Color Emoji"'));
210
+ console.log("[ugcinc-render/fonts] All fonts in document.fonts:");
211
+ document.fonts.forEach((font) => {
212
+ console.log(` - ${font.family}: weight=${font.weight}, style=${font.style}, status=${font.status}`);
213
+ });
214
+ console.log("[ugcinc-render/fonts] Font family stacks:");
215
+ console.log(" - tiktok:", FONT_FAMILIES.tiktok);
216
+ console.log(" - apple:", FONT_FAMILIES.apple);
217
+ console.log(" - arial:", FONT_FAMILIES.arial);
218
+ console.log("[ugcinc-render/fonts] === END FONT DEBUG ===");
145
219
  }
146
220
 
147
221
  // src/utils/text.ts
@@ -241,15 +315,48 @@ function calculateAutoWidthAndLines({
241
315
  letterSpacing,
242
316
  lineHeight
243
317
  }) {
318
+ console.log("[TextElement/calculateAutoWidthAndLines] ===== START CALCULATION =====");
319
+ console.log("[TextElement/calculateAutoWidthAndLines] Input params:", {
320
+ text: text.substring(0, 100) + (text.length > 100 ? "..." : ""),
321
+ textLength: text.length,
322
+ maxWidth,
323
+ paddingLeft,
324
+ paddingRight,
325
+ fontSize,
326
+ fontWeight,
327
+ fontFamily,
328
+ letterSpacing,
329
+ lineHeight
330
+ });
244
331
  if (typeof document === "undefined") {
332
+ console.log("[TextElement/calculateAutoWidthAndLines] SSR mode - returning maxWidth");
245
333
  return { width: maxWidth, lines: [text] };
246
334
  }
335
+ if (typeof document.fonts !== "undefined") {
336
+ const fontChecks = {
337
+ "SF Pro normal": document.fonts.check(`normal ${fontSize}px "SF Pro"`),
338
+ "SF Pro bold": document.fonts.check(`bold ${fontSize}px "SF Pro"`),
339
+ "TikTok Sans normal": document.fonts.check(`normal ${fontSize}px "TikTok Sans"`),
340
+ "TikTok Sans bold": document.fonts.check(`bold ${fontSize}px "TikTok Sans"`),
341
+ "requestedFont": document.fonts.check(`${fontWeight} ${fontSize}px ${fontFamily.split(",")[0]}`)
342
+ };
343
+ console.log("[TextElement/calculateAutoWidthAndLines] Font loading status:", fontChecks);
344
+ const loadedFonts = [];
345
+ document.fonts.forEach((font) => {
346
+ loadedFonts.push(`${font.family} (weight: ${font.weight}, status: ${font.status})`);
347
+ });
348
+ console.log("[TextElement/calculateAutoWidthAndLines] All document.fonts:", loadedFonts);
349
+ } else {
350
+ console.log("[TextElement/calculateAutoWidthAndLines] document.fonts API not available");
351
+ }
247
352
  const availableWidth = maxWidth - paddingLeft - paddingRight;
353
+ console.log("[TextElement/calculateAutoWidthAndLines] Available width for text:", availableWidth);
248
354
  if (availableWidth <= 0) {
355
+ console.log("[TextElement/calculateAutoWidthAndLines] Available width <= 0, returning maxWidth");
249
356
  return { width: maxWidth, lines: [text] };
250
357
  }
251
358
  const measureSpan = document.createElement("span");
252
- measureSpan.style.cssText = `
359
+ const cssText = `
253
360
  position: absolute;
254
361
  visibility: hidden;
255
362
  pointer-events: none;
@@ -259,16 +366,29 @@ function calculateAutoWidthAndLines({
259
366
  letter-spacing: ${letterSpacing}px;
260
367
  white-space: nowrap;
261
368
  `;
369
+ measureSpan.style.cssText = cssText;
370
+ console.log("[TextElement/calculateAutoWidthAndLines] Measurement span CSS:", cssText.replace(/\s+/g, " ").trim());
262
371
  document.body.appendChild(measureSpan);
263
372
  const measureText = (textToMeasure) => {
264
373
  measureSpan.textContent = textToMeasure;
265
- return measureSpan.getBoundingClientRect().width;
374
+ const width = measureSpan.getBoundingClientRect().width;
375
+ return width;
266
376
  };
267
377
  measureSpan.textContent = "M";
268
378
  const charWidth = measureSpan.getBoundingClientRect().width;
379
+ console.log('[TextElement/calculateAutoWidthAndLines] Single "M" character width:', charWidth);
380
+ measureSpan.textContent = "Test String";
381
+ const testStringWidth = measureSpan.getBoundingClientRect().width;
382
+ console.log('[TextElement/calculateAutoWidthAndLines] "Test String" width:', testStringWidth);
383
+ const computedStyle = window.getComputedStyle(measureSpan);
384
+ console.log("[TextElement/calculateAutoWidthAndLines] Computed font-family:", computedStyle.fontFamily);
385
+ console.log("[TextElement/calculateAutoWidthAndLines] Computed font-size:", computedStyle.fontSize);
386
+ console.log("[TextElement/calculateAutoWidthAndLines] Computed font-weight:", computedStyle.fontWeight);
387
+ console.log("[TextElement/calculateAutoWidthAndLines] Computed letter-spacing:", computedStyle.letterSpacing);
269
388
  const words = text.split(/(\s+)/);
270
389
  const lines = [];
271
390
  let currentLine = "";
391
+ console.log("[TextElement/calculateAutoWidthAndLines] Word count:", words.filter((w) => w.trim()).length);
272
392
  for (let i = 0; i < words.length; i++) {
273
393
  const word = words[i];
274
394
  if (word === "\n" || word === "\r\n") {
@@ -324,15 +444,60 @@ function calculateAutoWidthAndLines({
324
444
  lines.push("");
325
445
  }
326
446
  let widestLineWidth = 0;
447
+ const lineWidths = [];
327
448
  for (const line of lines) {
328
449
  const lineWidth = measureText(line);
450
+ lineWidths.push({ line: line.substring(0, 50) + (line.length > 50 ? "..." : ""), width: lineWidth });
329
451
  widestLineWidth = Math.max(widestLineWidth, lineWidth);
330
452
  }
453
+ console.log("[TextElement/calculateAutoWidthAndLines] Line measurements:", lineWidths);
454
+ console.log("[TextElement/calculateAutoWidthAndLines] Widest line width:", widestLineWidth);
331
455
  document.body.removeChild(measureSpan);
332
456
  const calculatedWidth = Math.min(widestLineWidth + paddingLeft + paddingRight, maxWidth);
457
+ console.log("[TextElement/calculateAutoWidthAndLines] Final calculation:", {
458
+ widestLineWidth,
459
+ paddingLeft,
460
+ paddingRight,
461
+ rawCalculatedWidth: widestLineWidth + paddingLeft + paddingRight,
462
+ cappedToMaxWidth: calculatedWidth,
463
+ maxWidth
464
+ });
465
+ console.log("[TextElement/calculateAutoWidthAndLines] ===== END CALCULATION =====");
333
466
  return { width: calculatedWidth, lines };
334
467
  }
335
468
  function TextElement({ segment, scale = 1 }) {
469
+ React.useEffect(() => {
470
+ const fontFamily2 = getFontFamily(segment.fontType ?? TEXT_DEFAULTS.fontType);
471
+ console.log("[TextElement] ===== RENDER EFFECT =====");
472
+ console.log("[TextElement] Segment ID:", segment.id);
473
+ console.log("[TextElement] Rendering with:", {
474
+ text: segment.text?.substring(0, 50) + (segment.text?.length > 50 ? "..." : ""),
475
+ fontType: segment.fontType ?? TEXT_DEFAULTS.fontType,
476
+ fontFamily: fontFamily2,
477
+ hasEmojis: /[\u{1F300}-\u{1F9FF}]/u.test(segment.text || ""),
478
+ autoWidth: segment.autoWidth,
479
+ boxAlign: segment.boxAlign
480
+ });
481
+ console.log("[TextElement] Segment dimensions:", {
482
+ xOffset: segment.xOffset,
483
+ yOffset: segment.yOffset,
484
+ width: segment.width,
485
+ height: segment.height
486
+ });
487
+ console.log("[TextElement] Segment padding:", {
488
+ paddingTop: segment.paddingTop,
489
+ paddingRight: segment.paddingRight,
490
+ paddingBottom: segment.paddingBottom,
491
+ paddingLeft: segment.paddingLeft
492
+ });
493
+ console.log("[TextElement] Segment font styling:", {
494
+ fontSize: segment.fontSize,
495
+ fontWeight: segment.fontWeight,
496
+ letterSpacing: segment.letterSpacing,
497
+ lineHeight: segment.lineHeight
498
+ });
499
+ console.log("[TextElement] Scale:", scale);
500
+ }, [segment, scale]);
336
501
  const fontType = segment.fontType ?? TEXT_DEFAULTS.fontType;
337
502
  const fontSize = (segment.fontSize ?? TEXT_DEFAULTS.fontSize) * scale;
338
503
  const fontWeight = segment.fontWeight ?? TEXT_DEFAULTS.fontWeight;
@@ -411,7 +576,7 @@ function TextElement({ segment, scale = 1 }) {
411
576
  lineHeight
412
577
  });
413
578
  }
414
- return {
579
+ const result = {
415
580
  calculatedWidth: autoWidth ? finalResult.width : width,
416
581
  calculatedLines: autoWidth ? finalResult.lines : [segment.text],
417
582
  paddingTop: finalPaddingTop,
@@ -419,6 +584,19 @@ function TextElement({ segment, scale = 1 }) {
419
584
  paddingBottom: finalPaddingBottom,
420
585
  paddingLeft: finalPaddingLeft
421
586
  };
587
+ console.log("[TextElement/useMemo] ===== FINAL VALUES =====");
588
+ console.log("[TextElement/useMemo] autoWidth:", autoWidth);
589
+ console.log("[TextElement/useMemo] calculatedWidth:", result.calculatedWidth);
590
+ console.log("[TextElement/useMemo] calculatedLines:", result.calculatedLines);
591
+ console.log("[TextElement/useMemo] Final padding:", {
592
+ top: result.paddingTop,
593
+ right: result.paddingRight,
594
+ bottom: result.paddingBottom,
595
+ left: result.paddingLeft
596
+ });
597
+ console.log("[TextElement/useMemo] Element width (maxWidth):", width);
598
+ console.log("[TextElement/useMemo] Difference (maxWidth - calculatedWidth):", width - result.calculatedWidth);
599
+ return result;
422
600
  }, [
423
601
  autoWidth,
424
602
  segment.text,
@@ -533,11 +711,29 @@ function TextElement({ segment, scale = 1 }) {
533
711
  verticalAlign
534
712
  ]);
535
713
  if (autoWidth) {
714
+ console.log("[TextElement/render] ===== RENDERING WITH AUTO-WIDTH =====");
715
+ console.log("[TextElement/render] Segment ID:", segment.id);
716
+ console.log("[TextElement/render] calculatedWidth being applied:", calculatedWidth);
717
+ console.log("[TextElement/render] maxWidth (element width):", width);
718
+ console.log("[TextElement/render] boxAlign:", boxAlign);
719
+ console.log("[TextElement/render] textAlign:", alignment);
720
+ console.log("[TextElement/render] Number of lines:", calculatedLines.length);
721
+ console.log("[TextElement/render] textStyle padding:", textStyle.padding);
722
+ console.log("[TextElement/render] textStyle fontFamily:", textStyle.fontFamily);
723
+ console.log("[TextElement/render] textStyle fontSize:", textStyle.fontSize);
724
+ console.log("[TextElement/render] textStyle letterSpacing:", textStyle.letterSpacing);
536
725
  const textContent = calculatedLines.map((line, index) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
537
726
  line,
538
727
  index < calculatedLines.length - 1 && /* @__PURE__ */ jsx("br", {})
539
728
  ] }, index));
540
729
  if (backgroundColor) {
730
+ console.log("[TextElement/render] Rendering WITH background");
731
+ console.log("[TextElement/render] Background wrapper style:", {
732
+ width: calculatedWidth,
733
+ maxWidth: width,
734
+ backgroundColor: hexToRgba(backgroundColor, backgroundOpacity),
735
+ borderRadius: borderRadiusStyle
736
+ });
541
737
  return /* @__PURE__ */ jsx("div", { style: positioningContainerStyle, children: /* @__PURE__ */ jsx(
542
738
  "div",
543
739
  {
@@ -551,6 +747,7 @@ function TextElement({ segment, scale = 1 }) {
551
747
  }
552
748
  ) });
553
749
  }
750
+ console.log("[TextElement/render] Rendering WITHOUT background");
554
751
  return /* @__PURE__ */ jsx("div", { style: positioningContainerStyle, children: /* @__PURE__ */ jsx("div", { style: { width: calculatedWidth, maxWidth: width }, children: /* @__PURE__ */ jsx("div", { style: textStyle, children: textContent }) }) });
555
752
  }
556
753
  return /* @__PURE__ */ jsx("div", { style: positioningContainerStyle, children: /* @__PURE__ */ jsx("div", { style: backgroundBoxStyle, children: /* @__PURE__ */ jsx("div", { style: textStyle, children: segment.text }) }) });
@@ -1073,7 +1270,7 @@ function getSortedSegments(config) {
1073
1270
  });
1074
1271
  }
1075
1272
  function elementToTextSegment(elem) {
1076
- return {
1273
+ const segment = {
1077
1274
  id: elem.id,
1078
1275
  type: "text",
1079
1276
  source: "",
@@ -1111,6 +1308,27 @@ function elementToTextSegment(elem) {
1111
1308
  autoWidth: elem.autoWidth,
1112
1309
  boxAlign: elem.boxAlign
1113
1310
  };
1311
+ console.log("[ImageEditorComposition/elementToTextSegment] ===== CONVERTING ELEMENT TO SEGMENT =====");
1312
+ console.log("[ImageEditorComposition/elementToTextSegment] Element ID:", elem.id);
1313
+ console.log("[ImageEditorComposition/elementToTextSegment] Element text:", (elem.text ?? "").substring(0, 50));
1314
+ console.log("[ImageEditorComposition/elementToTextSegment] Element dimensions:", { x: elem.x, y: elem.y, width: elem.width, height: elem.height });
1315
+ console.log("[ImageEditorComposition/elementToTextSegment] Element padding:", {
1316
+ paddingTop: elem.paddingTop,
1317
+ paddingRight: elem.paddingRight,
1318
+ paddingBottom: elem.paddingBottom,
1319
+ paddingLeft: elem.paddingLeft
1320
+ });
1321
+ console.log("[ImageEditorComposition/elementToTextSegment] Element autoWidth:", elem.autoWidth, "boxAlign:", elem.boxAlign);
1322
+ console.log("[ImageEditorComposition/elementToTextSegment] Element font:", elem.font, "fontSize:", elem.fontSize, "fontWeight:", elem.fontWeight);
1323
+ console.log("[ImageEditorComposition/elementToTextSegment] Element letterSpacing:", elem.letterSpacing, "lineHeight:", elem.lineHeight);
1324
+ console.log("[ImageEditorComposition/elementToTextSegment] Segment created:", {
1325
+ fontType: segment.fontType,
1326
+ fontSize: segment.fontSize,
1327
+ fontWeight: segment.fontWeight,
1328
+ letterSpacing: segment.letterSpacing,
1329
+ lineHeight: segment.lineHeight
1330
+ });
1331
+ return segment;
1114
1332
  }
1115
1333
  function elementToImageSegment(elem, source) {
1116
1334
  return {
@@ -1146,8 +1364,20 @@ function ImageEditorComposition({
1146
1364
  textValues = {},
1147
1365
  dynamicCrop
1148
1366
  }) {
1367
+ console.log("[ImageEditorComposition] ===== COMPOSITION RENDER =====");
1368
+ console.log("[ImageEditorComposition] Props received:", {
1369
+ hasConfig: !!config,
1370
+ hasElements: !!elements,
1371
+ elementCount: elements?.length ?? 0,
1372
+ width,
1373
+ height,
1374
+ scale,
1375
+ backgroundType,
1376
+ textValuesKeys: Object.keys(textValues)
1377
+ });
1149
1378
  const canvasWidth = width ?? config?.width ?? 1080;
1150
1379
  const canvasHeight = height ?? config?.height ?? 1920;
1380
+ console.log("[ImageEditorComposition] Canvas dimensions:", { canvasWidth, canvasHeight });
1151
1381
  const resolvedElements = useMemo3(() => {
1152
1382
  if (!elements) return null;
1153
1383
  const result = resolveElementPositions(elements, textValues);
@@ -1872,6 +2102,7 @@ export {
1872
2102
  calculateLineWidth,
1873
2103
  calculateTimelineContentEnd,
1874
2104
  canSetAsReference,
2105
+ debugFontStatus,
1875
2106
  defaultOffset,
1876
2107
  formatTime,
1877
2108
  generateOverlayId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugcinc-render",
3
- "version": "1.5.16",
3
+ "version": "1.5.18",
4
4
  "description": "Unified rendering package for UGC Inc - shared types, components, and compositions for pixel-perfect client/server rendering",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",