Skip to content

Commit

Permalink
feat: public API for fluent presentation builder
Browse files Browse the repository at this point in the history
  • Loading branch information
sergey-tihon committed Oct 6, 2024
1 parent bad31c7 commit 44bf4eb
Show file tree
Hide file tree
Showing 7 changed files with 1,579 additions and 1,554 deletions.
118 changes: 118 additions & 0 deletions Clippit/PowerPoint/Fluent/FluentPresentationBuilder.Deduplication.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
using System;
using System.Collections.Generic;
using System.Linq;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Presentation;

namespace Clippit.PowerPoint.Fluent;

internal partial class FluentPresentationBuilder
{
private readonly List<ContentData> _mediaCache = [];
private readonly List<SlideMasterData> _slideMasterList = [];
private SlideSize _slideSize;

private void InitializeCaches()
{
if (_newDocument.PresentationPart is not { } presentation)
return;

foreach (var slideMasterPart in presentation.SlideMasterParts)
{
foreach (var slideLayoutPart in slideMasterPart.SlideLayoutParts)
{
_ = GetOrAddSlideLayoutPart(_newDocument, slideLayoutPart, 1.0f);
}
}

// TODO: enumerate all images, media, master and layouts
_slideSize = presentation.Presentation.SlideSize;
}

private double GetScaleFactor(PresentationDocument sourceDocument)
{
var slideSize = sourceDocument.PresentationPart.Presentation.SlideSize;
var scaleFactorX = (double)_slideSize.Cx / slideSize.Cx;
var scaleFactorY = (double)_slideSize.Cy / slideSize.Cy;
return Math.Min(scaleFactorX, scaleFactorY);
}

// General function for handling images that tries to use an existing image if they are the same
private ImageData GetOrAddImageCopy(ImagePart oldImage)
{
return GetOrAddCachedMedia(new ImageData(oldImage));
}

// General function for handling media that tries to use an existing media item if they are the same
private MediaData GetOrAddMediaCopy(DataPart oldMedia)
{
return GetOrAddCachedMedia(new MediaData(oldMedia));
}

private T GetOrAddCachedMedia<T>(T contentData)
where T : ContentData
{
var duplicateItem = _mediaCache.FirstOrDefault(x => x.Compare(contentData));
if (duplicateItem != null)
{
return (T)duplicateItem;
}

_mediaCache.Add(contentData);
return contentData;
}

// General function for handling SlideMasterPart that tries to use an existing SlideMasterPart if they are the same
private SlideMasterData GetOrAddSlideMasterPart(
PresentationDocument presentationDocument,
SlideMasterPart slideMasterPart,
double scaleFactor
)
{
var slideMasterData = new SlideMasterData(slideMasterPart, scaleFactor);
foreach (var item in _slideMasterList)
{
if (item.CompareTo(slideMasterData) == 0)
return item;
}

if (!ReferenceEquals(presentationDocument, _newDocument))
{
var newSlideMasterPart = CopySlideMasterPart(slideMasterPart, scaleFactor);
slideMasterData = new SlideMasterData(newSlideMasterPart, 1.0);
}

_slideMasterList.Add(slideMasterData);
return slideMasterData;
}

// General function for handling SlideMasterPart that tries to use an existing SlideMasterPart if they are the same
private SlideLayoutData GetOrAddSlideLayoutPart(
PresentationDocument presentationDocument,
SlideLayoutPart slideLayoutPart,
double scaleFactor
)
{
var slideMasterData = GetOrAddSlideMasterPart(
presentationDocument,
slideLayoutPart.SlideMasterPart,
scaleFactor
);

var slideLayoutData = new SlideLayoutData(slideLayoutPart, scaleFactor);
foreach (var item in slideMasterData.SlideLayoutList)
{
if (item.CompareTo(slideLayoutData) == 0)
return item;
}

if (!ReferenceEquals(presentationDocument, _newDocument))
{
var newSlideLayoutPart = CopySlideLayoutPart(slideMasterData.Part, slideLayoutPart, scaleFactor);
slideLayoutData = new SlideLayoutData(newSlideLayoutPart, 1.0);
}

slideMasterData.SlideLayoutList.Add(slideLayoutData);
return slideLayoutData;
}
}
Loading

0 comments on commit 44bf4eb

Please sign in to comment.