Bloom.Publish.EpubMaker.FixPictureSizes C# (CSharp) Method

FixPictureSizes() private method

Typically pictures are given an absolute size in px, which looks right given the current absolute size of the page it is on. For an ePUB, a percent size will work better. We calculate it based on the page sizes and margins in BasePage.less and commonMixins.less. The page size definitions are unlikely to change, but change might be needed here if there is a change to the main .marginBox rule in basePage.less. To partly accommodate origami pages, we adjust for parent divs with an explict style setting the percent width.
private FixPictureSizes ( HtmlDom pageDom ) : void
pageDom Bloom.Book.HtmlDom
return void
        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);
            }
        }