private void FixPictureSizes(HtmlDom pageDom)
{
bool firstTime = true;
double pageWidthMm = 210; // assume A5 Portrait if not specified
foreach (XmlElement img in HtmlDom.SelectChildImgAndBackgroundImageElements(pageDom.RawDom.DocumentElement))
{
var parent = img.ParentNode.ParentNode as XmlElement;
var mulitplier = 1.0;
// For now we only attempt to adjust pictures contained in the marginBox.
// To do better than this we will probably need to actually load the HTML into
// a browser; even then it will be complex.
while (parent != null && !HasClass(parent, "marginBox"))
{
// 'marginBox' is not yet the margin box...it is some parent div.
// If it has an explicit percent width style, adjust for this.
var styleAttr = parent.Attributes["style"];
if (styleAttr != null)
{
var style = styleAttr.Value;
var match = new Regex("width:\\s*(\\d+(\\.\\d+)?)%").Match(style);
if (match.Success)
{
double percent;
if (Double.TryParse(match.Groups[1].Value, out percent))
{
mulitplier *= percent/100;
}
}
}
parent = parent.ParentNode as XmlElement;
}
if (parent == null)
continue;
var page = parent.ParentNode as XmlElement;
if (!HasClass(page, "bloom-page"))
continue; // or return? marginBox should be child of page!
if (firstTime)
{
var pageClass = HtmlDom.GetAttributeValue(page, "class").Split().FirstOrDefault(c => c.Contains("Portrait") || c.Contains("Landscape"));
// This calculation unfortunately duplicates information from basePage.less.
const int A4Width = 210;
const int A4Height = 297;
const double letterPortraitHeight = 11.0 * mmPerInch;
const double letterPortraitWidth = 8.5 * mmPerInch;
const double legalPortraitHeight = 14.0 * mmPerInch;
const double legalPortraitWidth = 8.5 * mmPerInch;
switch (pageClass)
{
case "A3Landscape":
pageWidthMm = A4Width*2.0;
break;
case "A5Portrait":
pageWidthMm = A4Height/2.0;
break;
case "A4Portrait":
pageWidthMm = A4Width;
break;
case "A5Landscape":
pageWidthMm = A4Width / 2.0;
break;
case "A3Portrait":
case "A4Landscape":
pageWidthMm = A4Height;
break;
case "A6Portrait":
pageWidthMm = A4Width / 2.0;
break;
case "A6Landscape":
pageWidthMm = A4Height / 2.0;
break;
case "B5Portrait":
pageWidthMm = 176;
break;
case "QuarterLetterPortrait":
pageWidthMm = letterPortraitWidth/2.0;
break;
case "QuarterLetterLandscape":
case "HalfLetterPortrait":
pageWidthMm = letterPortraitHeight / 2.0;
break;
case "HalfLetterLandscape":
case "LetterPortrait":
pageWidthMm = letterPortraitWidth;
break;
case "LetterLandscape":
pageWidthMm = letterPortraitHeight;
break;
case "HalfLegalPortrait":
pageWidthMm = legalPortraitHeight / 2.0;
break;
case "HalfLegalLandscape":
case "LegalPortrait":
pageWidthMm = legalPortraitWidth;
break;
case "LegalLandscape":
pageWidthMm = legalPortraitHeight;
break;
}
firstTime = false;
}
var imgStyle = HtmlDom.GetAttributeValue(img, "style");
// We want to take something like 'width:334px; height:220px; margin-left: 34px; margin-top: 0px;'
// and change it to something like 'width:75%; height:auto; margin-left: 10%; margin-top: 0px;'
// This first pass deals with width.
if (ConvertStyleFromPxToPercent("width", pageWidthMm, mulitplier, ref imgStyle)) continue;
// Now change height to auto, to preserve aspect ratio
imgStyle = new Regex("height:\\s*\\d+px").Replace(imgStyle, "height:auto");
if (!imgStyle.Contains("height"))
imgStyle = "height:auto; " + imgStyle;
// Similarly fix indent
ConvertStyleFromPxToPercent("margin-left", pageWidthMm, mulitplier, ref imgStyle);
img.SetAttribute("style", imgStyle);
}
}