public static LayoutMetadata applyStrictLayout(ISlide slide, LayoutMetadata
layoutMetadata) {
double pageWidth =
[Link]().getSlideSize().getSize().getWidth();
double pageHeight =
[Link]().getSlideSize().getSize().getHeight();
[Link]("== Applying Strict Layout with Full Horizontal
Alignment ==");
// === 1.1 Detect Title Placeholder ===
double titleX, titleY, titleCY, titleCX;
if ([Link]() == null) {
[Link]("Title placeholder not found, using fallback
values.");
titleX = libraryTitleXRatio * pageWidth;
titleY = libraryTitleYRatio * pageHeight;
titleCY = libraryTitleCYRatio * pageHeight;
titleCX = libraryTitleCXRatio * pageWidth;
} else {
titleX = [Link]().getX();
titleY = [Link]().getY();
titleCY = [Link]().getCy();
titleCX = [Link]().getCx();
}
// === 1.2 Detect Body Content Placeholder ===
double bodyX, bodyCX, bodyXD;
if ([Link]() == null) {
[Link]("Content placeholder not found, using fallback
values.");
bodyX = 0.0;
bodyCX = pageWidth;
bodyXD = pageWidth - bodyX - bodyCX;
} else {
bodyX = [Link]().getX();
bodyCX = [Link]().getCx();
bodyXD = pageWidth - bodyX - bodyCX;
}
// === 3.1 Use title dimensions for horizontal alignment ===
double titleXD = pageWidth - titleX - titleCX;
// === 3.2 Use title dimensions for horizontal alignment ===
titleX = clamp(titleX, marginXMinRatio * pageWidth, marginXMaxRatio *
pageWidth);
titleXD = clamp(titleXD, marginXMinRatio * pageWidth, marginXMaxRatio *
pageWidth);
titleCX = pageWidth - titleXD - titleX;
// Title ratios
double titleXRatio = titleX / pageWidth;
double titleXDRatio = titleXD / pageWidth;
// Content Ratios
/*
* The expected behavior: Priority 1: Try to keep contentX aligned with
title.
* ContentX takes titleX value if it's between contentMarginXMinRatio
and
* contentMarginXMaxRatio, (Eliminate possibilities between
* contentMarginXMaxRatio =0.075 - marginXMaxRatio= 0.15)
*
* Priority 2: Try to have symmetry between contentX and contentXD
ContentX
* takes titleXD value if titleXD is between contentMarginXMinRatio and
* contentMarginXMaxRatio (this will be the value of contentXD as
well).
*
* Priority 3: ContentX takes the default value
contentMarginXDefaultRatio
* because the title (very far from the slide borders) does not offer
enough
* space to render the library pages.
*/
boolean isBodyOk = inRange(bodyX / pageWidth, contentMarginXMinRatio,
contentMarginXMaxRatio)
&& inRange(bodyXD / pageWidth, contentMarginXMinRatio,
contentMarginXMaxRatio);
double contentX, contentXD;
if (!isBodyOk) {
contentX = (inRange(titleXRatio, contentMarginXMinRatio,
contentMarginXMaxRatio)) ? titleX
: (inRange(titleXDRatio, contentMarginXMinRatio,
contentMarginXMaxRatio)) ? titleXD
: contentMarginXDefaultRatio * pageWidth;
contentXD = (inRange(titleXDRatio, contentMarginXMinRatio,
contentMarginXMaxRatio)) ? titleXD
: (inRange(titleXRatio, contentMarginXMinRatio,
contentMarginXMaxRatio)) ? titleX
: contentMarginXDefaultRatio * pageWidth;
} else {
contentX = bodyX;
contentXD = bodyXD;
}
// === 4. Content height from derived cy_ratio
/*
* In step 3, contentX and XD are defined. So contentCX is a direct
consequence.
* contentCX and contentCY should always be using the proportionality
values of
* the slide library to avoid distorting shapes inside the content
zone.
* contentCY is calculated using the proportionality ratio
*/
double contentCX = pageWidth - contentX - contentXD;
double contentCXRatio = contentCX / pageWidth;
double contentCYRatio = (pageRatio / contentRatio) * contentCXRatio;
double contentCY = contentCYRatio * pageHeight;
// === 5. Clamp title height ===
// Must ensure 2 lines of text in the title
titleCY = clamp(titleCY, titleCYMinRatio * pageHeight, titleCYMaxRatio
* pageHeight);
// === 6. Vertical positioning ===
/*
* Once titleCY and contentCY defined, the rest of the vertical space
will be
* distributed between header, subtitle and footnote blocks
*/
double headerBlockMinRatio = upperSpace1Ratio + headerCYRatio +
upperSpace2Ratio;
double subtitleBlockMinRatio = upperSpace3Ratio + subtitleCYRatio +
upperSpace4Ratio;
double spaceBelowContentMin = spaceBelowContentRatio * pageHeight;
/*
* The titleY should allow enough space for the header block above, and
enough
* space for subtitle block + contentCY + footnote block below
*/
double titleYMin = headerBlockMinRatio * pageHeight;
double titleYMax = pageHeight
- (titleCY + (subtitleBlockMinRatio * pageHeight) +
contentCY + spaceBelowContentMin);
titleY = clamp(titleY, titleYMin, titleYMax);
double titleYRatio = titleY / pageHeight;
// === 7. Compute block positions ===
/*
* 7.1. Compute positions of header block above title. Available space
is
* titleY. Size and positions are computed proportionally to the min
values
*/
double headerY = upperSpace1Ratio * (titleYRatio / headerCYBlockRatio)
* pageHeight;
double headerCY = headerCYRatio * (titleYRatio / headerCYBlockRatio) *
pageHeight;
/*
* 7.2. Compute positions below title Interim calculation step: the
available
* space for subtitle block and footnote block is computed here, then
* distributed proportionally between the 2
*/
double availableSpaceForSubtitleAndBottomMargin = pageHeight - titleY -
titleCY - contentCY;
double availableSpaceForSubtitle =
availableSpaceForSubtitleAndBottomMargin * subtitleCYBlockRatio
/ (subtitleCYBlockRatio + spaceBelowContentRatio);
double availableSpaceForBottomMargin =
availableSpaceForSubtitleAndBottomMargin - availableSpaceForSubtitle;
/*
* 7.3. Compute block positions Subtitle Available space is
* availableSpaceForSubtitle. Size and positions are computed
proportionally to
* the min values
*/
double upperSpace3Final = availableSpaceForSubtitle * (upperSpace3Ratio
/ subtitleCYBlockRatio);
double subtitleCY = availableSpaceForSubtitle * (subtitleCYRatio /
subtitleCYBlockRatio);
double subtitleY = titleY + titleCY + upperSpace3Final;
// 7.4. Compute ContentY
double contentY = titleY + titleCY + availableSpaceForSubtitle;
/*
* 7.5 Compute block positions Footnote Available space is
* availableSpaceForBottomMargin. Size and positions are computed
proportionally
* to the min values
*/
double lowerSpace1Final = availableSpaceForBottomMargin *
(lowerSpace1Ratio / spaceBelowContentRatio);
double footnoteCY = availableSpaceForBottomMargin * (footnoteCYRatio /
spaceBelowContentRatio);
double footnoteY = contentY + contentCY + lowerSpace1Final;
[Link](new Zone(titleX, headerY, titleCX / 2,
headerCY));
[Link](new Zone(titleX, titleY, titleCX, titleCY));
[Link](new Zone(titleX, subtitleY, titleCX / 2,
subtitleCY));
[Link](new Zone(contentX, contentY, contentCX,
contentCY));
[Link](new Zone(contentX, footnoteY, contentCX,
footnoteCY));
[Link]("== Strict Layout Complete ==");
return layoutMetadata;
}
public static void applyPositions(ISlide slide, LayoutMetadata metadata) {
// In case we use maximize or ensureFit copy methods, the virtual
contentBox is
// the content box to which we apply the slide transformation
IAutoShape title = null;
for (IShape shape : [Link]()) {
if (shape instanceof IAutoShape) {
IAutoShape autoShape = (IAutoShape) shape;
if ([Link]() != null &&
([Link]().getType() == [Link]
|| [Link]().getType() ==
[Link])) {
title = autoShape;
break;
}
}
}
double contentCXVirtual = libraryContentCXRatio *
[Link]();
double contentCYVirtual = libraryContentCYRatio *
[Link]();
double contentXVirtual = libraryContentXRatio *
[Link]();
double contentYVirtual = libraryContentYRatio *
[Link]();
// === Apply title position ===
double titleX = [Link]().getX();
double titleCX = [Link]().getCx();
double titleCY = [Link]().getCy();
double titleY = [Link]().getY();
resizeTitle(title, titleX, titleCX, titleCY, titleY);
// === Apply Body position ===
double contentX = [Link]().getX();
double contentCX = [Link]().getCx();
double contentCY = [Link]().getCy();
double contentY = [Link]().getY();
// Iterate shapes and set X, Y ,CY, CX
resizeContent(slide, title, contentCXVirtual, contentCYVirtual,
contentXVirtual, contentYVirtual, contentX,
contentCX, contentCY, contentY);
// draw Boxes
double headerX = [Link]().getX();
double headerCX = [Link]().getCx();
double headerCY = [Link]().getCy();
double headerY = [Link]().getY();
double footnoteX = [Link]().getX();
double footnoteCX = [Link]().getCx();
double footnoteCY = [Link]().getCy();
double footnoteY = [Link]().getY();
double subtitleX = [Link]().getX();
double subtitleCX = [Link]().getCx();
double subtitleCY = [Link]().getCy();
double subtitleY = [Link]().getY();
double pageWidth = [Link]();
double pageHeight = [Link]();
double halfTitleCX = titleCX / 2;
drawBoxes(slide, pageWidth, pageHeight, titleX, titleCX, halfTitleCX,
contentX, contentCX, contentCY, headerY,
headerCY, subtitleCY, subtitleY, contentY, footnoteCY,
footnoteY);
// === Log layout blocks ===
drawLayoutZones(slide, pageWidth, pageHeight, titleX, titleCX, headerY,
headerCY, titleY, titleCY, subtitleY,
subtitleCY, contentY, contentCY, footnoteY, footnoteCY,
contentX, contentCX);
-----------------------------------------------------------------------------------
-----------------------------------------------------
-----------------------------------------------------------------------------------
-----------------------------------------------------
-----------------------------------------------------------------------------------
-----------------------------------------------------
-----------------------------------------------------------------------------------
-----------------------------------------------------
public LayoutMetadata initSlideStructure(Presentation newPresentation) {
LayoutMetadata contentAndTitleMetadata = null;
contentAndTitleMetadata = createContentAndZoneLayout(newPresentation);
[Link]();
removeAllSlides(newPresentation);
createTitleOnlyLayout(newPresentation);
return contentAndTitleMetadata;
}
public static void removeAllSlides(Presentation presentation) {
ISlideCollection slides = [Link]();
while ([Link]() > 0) {
[Link](0);
}
}
private LayoutMetadata createContentAndZoneLayout(Presentation
newPresentation) {
IMasterSlide master = [Link]().get_Item(0);
ILayoutSlide titleAndContent =
[Link]().add([Link], "XTitleAndContent");
ISlide slideCreatedWithTitleAndContent =
[Link]().addEmptySlide(titleAndContent);
LayoutInitializer init = new LayoutInitializer();
LayoutMetadata metadata = [Link](titleAndContent);
return [Link](slideCreatedWithTitleAndContent,
metadata);
}
private void createTitleOnlyLayout(Presentation newPresentation) {
IMasterSlide master = [Link]().get_Item(0);
[Link]().add([Link], "XTitleOnly");
}