@@ -457,8 +457,9 @@ async function renderPptxSlides(
457457 if ( cancelled ( ) ) return
458458
459459 const dpr = Math . min ( window . devicePixelRatio || 1 , 2 )
460- const W = Math . round ( 1920 * dpr )
461- const H = Math . round ( 1080 * dpr )
460+ const { width, height } = await getPptxRenderSize ( data , dpr )
461+ const W = width
462+ const H = height
462463
463464 const canvas = document . createElement ( 'canvas' )
464465 canvas . width = W
@@ -476,6 +477,48 @@ async function renderPptxSlides(
476477 }
477478}
478479
480+ async function getPptxRenderSize (
481+ data : Uint8Array ,
482+ dpr : number
483+ ) : Promise < { width : number ; height : number } > {
484+ const fallback = {
485+ width : Math . round ( 1920 * dpr ) ,
486+ height : Math . round ( 1080 * dpr ) ,
487+ }
488+
489+ try {
490+ const JSZip = ( await import ( 'jszip' ) ) . default
491+ const zip = await JSZip . loadAsync ( data )
492+ const presentationXml = await zip . file ( 'ppt/presentation.xml' ) ?. async ( 'text' )
493+ if ( ! presentationXml ) return fallback
494+
495+ const match = presentationXml . match ( / < p : s l d S z [ ^ > ] * c x = " ( \d + ) " [ ^ > ] * c y = " ( \d + ) " / )
496+ if ( ! match ) return fallback
497+
498+ const cx = Number ( match [ 1 ] )
499+ const cy = Number ( match [ 2 ] )
500+ if ( ! Number . isFinite ( cx ) || ! Number . isFinite ( cy ) || cx <= 0 || cy <= 0 ) return fallback
501+
502+ const aspectRatio = cx / cy
503+ if ( ! Number . isFinite ( aspectRatio ) || aspectRatio <= 0 ) return fallback
504+
505+ const baseLongEdge = 1920 * dpr
506+ if ( aspectRatio >= 1 ) {
507+ return {
508+ width : Math . round ( baseLongEdge ) ,
509+ height : Math . round ( baseLongEdge / aspectRatio ) ,
510+ }
511+ }
512+
513+ return {
514+ width : Math . round ( baseLongEdge * aspectRatio ) ,
515+ height : Math . round ( baseLongEdge ) ,
516+ }
517+ } catch {
518+ return fallback
519+ }
520+ }
521+
479522function PptxPreview ( {
480523 file,
481524 workspaceId,
0 commit comments