PageScaleConstraints ViewportDescription::resolve(const FloatSize& initialViewportSize, Length legacyFallbackWidth) const { float resultWidth = ValueAuto; Length copyMaxWidth = maxWidth; Length copyMinWidth = minWidth; // In case the width (used for min- and max-width) is undefined. if (isLegacyViewportType() && maxWidth.isAuto()) { // The width viewport META property is translated into 'width' descriptors, setting // the 'min' value to 'extend-to-zoom' and the 'max' value to the intended length. // In case the UA-defines a min-width, use that as length. if (zoom == ViewportDescription::ValueAuto) { copyMinWidth = Length(ExtendToZoom); copyMaxWidth = legacyFallbackWidth; } else if (maxHeight.isAuto()) { copyMinWidth = Length(ExtendToZoom); copyMaxWidth = Length(ExtendToZoom); } } float resultMaxWidth = resolveViewportLength(copyMaxWidth, initialViewportSize, Horizontal); float resultMinWidth = resolveViewportLength(copyMinWidth, initialViewportSize, Horizontal); float resultHeight = ValueAuto; float resultMaxHeight = resolveViewportLength(maxHeight, initialViewportSize, Vertical); float resultMinHeight = resolveViewportLength(minHeight, initialViewportSize, Vertical); float resultZoom = zoom; float resultMinZoom = minZoom; float resultMaxZoom = maxZoom; float resultUserZoom = userZoom; // 1. Resolve min-zoom and max-zoom values. if (resultMinZoom != ViewportDescription::ValueAuto && resultMaxZoom != ViewportDescription::ValueAuto) resultMaxZoom = max(resultMinZoom, resultMaxZoom); // 2. Constrain zoom value to the [min-zoom, max-zoom] range. if (resultZoom != ViewportDescription::ValueAuto) resultZoom = compareIgnoringAuto(resultMinZoom, compareIgnoringAuto(resultMaxZoom, resultZoom, min), max); float extendZoom = compareIgnoringAuto(resultZoom, resultMaxZoom, min); // 3. Resolve non-"auto" lengths to pixel lengths. if (extendZoom == ViewportDescription::ValueAuto) { if (resultMaxWidth == ViewportDescription::ValueExtendToZoom) resultMaxWidth = ViewportDescription::ValueAuto; if (resultMaxHeight == ViewportDescription::ValueExtendToZoom) resultMaxHeight = ViewportDescription::ValueAuto; if (resultMinWidth == ViewportDescription::ValueExtendToZoom) resultMinWidth = resultMaxWidth; if (resultMinHeight == ViewportDescription::ValueExtendToZoom) resultMinHeight = resultMaxHeight; } else { float extendWidth = initialViewportSize.width() / extendZoom; float extendHeight = initialViewportSize.height() / extendZoom; if (resultMaxWidth == ViewportDescription::ValueExtendToZoom) resultMaxWidth = extendWidth; if (resultMaxHeight == ViewportDescription::ValueExtendToZoom) resultMaxHeight = extendHeight; if (resultMinWidth == ViewportDescription::ValueExtendToZoom) resultMinWidth = compareIgnoringAuto(extendWidth, resultMaxWidth, max); if (resultMinHeight == ViewportDescription::ValueExtendToZoom) resultMinHeight = compareIgnoringAuto(extendHeight, resultMaxHeight, max); } // 4. Resolve initial width from min/max descriptors. if (resultMinWidth != ViewportDescription::ValueAuto || resultMaxWidth != ViewportDescription::ValueAuto) resultWidth = compareIgnoringAuto(resultMinWidth, compareIgnoringAuto(resultMaxWidth, initialViewportSize.width(), min), max); // 5. Resolve initial height from min/max descriptors. if (resultMinHeight != ViewportDescription::ValueAuto || resultMaxHeight != ViewportDescription::ValueAuto) resultHeight = compareIgnoringAuto(resultMinHeight, compareIgnoringAuto(resultMaxHeight, initialViewportSize.height(), min), max); // 6-7. Resolve width value. if (resultWidth == ViewportDescription::ValueAuto) { if (resultHeight == ViewportDescription::ValueAuto || !initialViewportSize.height()) resultWidth = initialViewportSize.width(); else resultWidth = resultHeight * (initialViewportSize.width() / initialViewportSize.height()); } // 8. Resolve height value. if (resultHeight == ViewportDescription::ValueAuto) { if (!initialViewportSize.width()) resultHeight = initialViewportSize.height(); else resultHeight = resultWidth * initialViewportSize.height() / initialViewportSize.width(); } // Resolve initial-scale value. if (resultZoom == ViewportDescription::ValueAuto) { if (resultWidth != ViewportDescription::ValueAuto && resultWidth > 0) resultZoom = initialViewportSize.width() / resultWidth; if (resultHeight != ViewportDescription::ValueAuto && resultHeight > 0) { // if 'auto', the initial-scale will be negative here and thus ignored. resultZoom = max<float>(resultZoom, initialViewportSize.height() / resultHeight); } } // If user-scalable = no, lock the min/max scale to the computed initial // scale. if (!resultUserZoom) resultMinZoom = resultMaxZoom = resultZoom; // Only set initialScale to a value if it was explicitly set. if (zoom == ViewportDescription::ValueAuto) resultZoom = ViewportDescription::ValueAuto; PageScaleConstraints result; result.minimumScale = resultMinZoom; result.maximumScale = resultMaxZoom; result.initialScale = resultZoom; result.layoutSize.setWidth(resultWidth); result.layoutSize.setHeight(resultHeight); return result; }
ViewportAttributes ViewportArguments::resolve(const FloatSize& initialViewportSize, const FloatSize& deviceSize, int defaultWidth) const { float resultWidth = width; float resultMaxWidth = maxWidth; float resultMinWidth = minWidth; float resultHeight = height; float resultMinHeight = minHeight; float resultMaxHeight = maxHeight; float resultZoom = zoom; float resultMinZoom = minZoom; float resultMaxZoom = maxZoom; float resultUserZoom = userZoom; switch (int(resultWidth)) { case ViewportArguments::ValueDeviceWidth: resultWidth = deviceSize.width(); break; case ViewportArguments::ValueDeviceHeight: resultWidth = deviceSize.height(); break; } switch (int(resultHeight)) { case ViewportArguments::ValueDeviceWidth: resultHeight = deviceSize.width(); break; case ViewportArguments::ValueDeviceHeight: resultHeight = deviceSize.height(); break; } if (type == ViewportArguments::CSSDeviceAdaptation) { switch (int(resultMinWidth)) { case ViewportArguments::ValueDeviceWidth: resultMinWidth = deviceSize.width(); break; case ViewportArguments::ValueDeviceHeight: resultMinWidth = deviceSize.height(); break; } switch (int(resultMaxWidth)) { case ViewportArguments::ValueDeviceWidth: resultMaxWidth = deviceSize.width(); break; case ViewportArguments::ValueDeviceHeight: resultMaxWidth = deviceSize.height(); break; } switch (int(resultMinHeight)) { case ViewportArguments::ValueDeviceWidth: resultMinHeight = deviceSize.width(); break; case ViewportArguments::ValueDeviceHeight: resultMinHeight = deviceSize.height(); break; } switch (int(resultMaxHeight)) { case ViewportArguments::ValueDeviceWidth: resultMaxHeight = deviceSize.width(); break; case ViewportArguments::ValueDeviceHeight: resultMaxHeight = deviceSize.height(); break; } if (resultMinWidth != ViewportArguments::ValueAuto || resultMaxWidth != ViewportArguments::ValueAuto) resultWidth = compareIgnoringAuto(resultMinWidth, compareIgnoringAuto(resultMaxWidth, deviceSize.width(), min), max); if (resultMinHeight != ViewportArguments::ValueAuto || resultMaxHeight != ViewportArguments::ValueAuto) resultHeight = compareIgnoringAuto(resultMinHeight, compareIgnoringAuto(resultMaxHeight, deviceSize.height(), min), max); if (resultMinZoom != ViewportArguments::ValueAuto && resultMaxZoom != ViewportArguments::ValueAuto) resultMaxZoom = max(resultMinZoom, resultMaxZoom); if (resultZoom != ViewportArguments::ValueAuto) resultZoom = compareIgnoringAuto(resultMinZoom, compareIgnoringAuto(resultMaxZoom, resultZoom, min), max); if (resultWidth == ViewportArguments::ValueAuto && resultZoom == ViewportArguments::ValueAuto) resultWidth = deviceSize.width(); if (resultWidth == ViewportArguments::ValueAuto && resultHeight == ViewportArguments::ValueAuto) resultWidth = deviceSize.width() / resultZoom; if (resultWidth == ViewportArguments::ValueAuto) resultWidth = resultHeight * deviceSize.width() / deviceSize.height(); if (resultHeight == ViewportArguments::ValueAuto) resultHeight = resultWidth * deviceSize.height() / deviceSize.width(); if (resultZoom != ViewportArguments::ValueAuto || resultMaxZoom != ViewportArguments::ValueAuto) { resultWidth = compareIgnoringAuto(resultWidth, deviceSize.width() / compareIgnoringAuto(resultZoom, resultMaxZoom, min), max); resultHeight = compareIgnoringAuto(resultHeight, deviceSize.height() / compareIgnoringAuto(resultZoom, resultMaxZoom, min), max); } } // Clamp values to valid range. resultWidth = clampLengthValue(resultWidth); resultHeight = clampLengthValue(resultHeight); resultZoom = clampScaleValue(resultZoom); resultMinZoom = clampScaleValue(resultMinZoom); resultMaxZoom = clampScaleValue(resultMaxZoom); ViewportAttributes result; result.orientation = orientation; // Resolve minimum-scale and maximum-scale values according to spec. if (resultMinZoom == ViewportArguments::ValueAuto) result.minimumScale = float(0.25); else result.minimumScale = resultMinZoom; if (resultMaxZoom == ViewportArguments::ValueAuto) { result.maximumScale = float(5.0); result.minimumScale = min(float(5.0), result.minimumScale); } else result.maximumScale = resultMaxZoom; result.maximumScale = max(result.minimumScale, result.maximumScale); // Resolve initial-scale value. result.initialScale = resultZoom; if (resultZoom == ViewportArguments::ValueAuto) { result.initialScale = initialViewportSize.width() / defaultWidth; if (resultWidth != ViewportArguments::ValueAuto) result.initialScale = initialViewportSize.width() / resultWidth; if (resultHeight != ViewportArguments::ValueAuto) { // if 'auto', the initial-scale will be negative here and thus ignored. result.initialScale = max<float>(result.initialScale, initialViewportSize.height() / resultHeight); } } // Constrain initial-scale value to minimum-scale/maximum-scale range. result.initialScale = min(result.maximumScale, max(result.minimumScale, result.initialScale)); // Resolve width value. if (resultWidth == ViewportArguments::ValueAuto) { if (resultZoom == ViewportArguments::ValueAuto) resultWidth = defaultWidth; else if (resultHeight != ViewportArguments::ValueAuto) resultWidth = resultHeight * (initialViewportSize.width() / initialViewportSize.height()); else resultWidth = initialViewportSize.width() / result.initialScale; } // Resolve height value. if (resultHeight == ViewportArguments::ValueAuto) resultHeight = resultWidth * (initialViewportSize.height() / initialViewportSize.width()); // Extend width and height to fill the visual viewport for the resolved initial-scale. resultWidth = max<float>(resultWidth, initialViewportSize.width() / result.initialScale); resultHeight = max<float>(resultHeight, initialViewportSize.height() / result.initialScale); result.layoutSize.setWidth(resultWidth); result.layoutSize.setHeight(resultHeight); // FIXME: This might affect some ports, but is the right thing to do. // Only set initialScale to a value if it was explicitly set. // if (resultZoom == ViewportArguments::ValueAuto) // result.initialScale = ViewportArguments::ValueAuto; result.userScalable = resultUserZoom; result.orientation = orientation; return result; }