CSSImageSetValue.cpp [plain text]
#include "config.h"
#include "CSSImageSetValue.h"
#if ENABLE(CSS_IMAGE_SET)
#include "CSSImageValue.h"
#include "CSSPrimitiveValue.h"
#include "CachedResourceLoader.h"
#include "Document.h"
#include "Page.h"
#include "StyleCachedImageSet.h"
#include "StylePendingImage.h"
namespace WebCore {
CSSImageSetValue::CSSImageSetValue()
: CSSValueList(ImageSetClass, CommaSeparator)
, m_accessedBestFitImage(false)
, m_scaleFactor(1)
{
}
CSSImageSetValue::~CSSImageSetValue()
{
}
void CSSImageSetValue::fillImageSet()
{
size_t length = this->length();
size_t i = 0;
while (i < length) {
CSSValue* imageValue = item(i);
ASSERT(imageValue->isImageValue());
String imageURL = static_cast<CSSImageValue*>(imageValue)->url();
++i;
ASSERT(i < length);
CSSValue* scaleFactorValue = item(i);
ASSERT(scaleFactorValue->isPrimitiveValue());
float scaleFactor = static_cast<CSSPrimitiveValue*>(scaleFactorValue)->getFloatValue();
ImageWithScale image;
image.imageURL = imageURL;
image.scaleFactor = scaleFactor;
m_imagesInSet.append(image);
++i;
}
std::sort(m_imagesInSet.begin(), m_imagesInSet.end(), CSSImageSetValue::compareByScaleFactor);
}
CSSImageSetValue::ImageWithScale CSSImageSetValue::bestImageForScaleFactor()
{
ImageWithScale image;
size_t numberOfImages = m_imagesInSet.size();
for (size_t i = 0; i < numberOfImages; ++i) {
image = m_imagesInSet.at(i);
if (image.scaleFactor >= m_scaleFactor)
return image;
}
return image;
}
StyleCachedImageSet* CSSImageSetValue::cachedImageSet(CachedResourceLoader* loader)
{
ASSERT(loader);
Document* document = loader->document();
if (Page* page = document->page())
m_scaleFactor = page->deviceScaleFactor();
else
m_scaleFactor = 1;
if (!m_imagesInSet.size())
fillImageSet();
if (!m_accessedBestFitImage) {
ImageWithScale image = bestImageForScaleFactor();
ResourceRequest request(loader->document()->completeURL(image.imageURL));
if (CachedResourceHandle<CachedImage> cachedImage = loader->requestImage(request)) {
m_imageSet = StyleCachedImageSet::create(cachedImage.get(), image.scaleFactor, this);
m_accessedBestFitImage = true;
}
}
return (m_imageSet && m_imageSet->isCachedImageSet()) ? static_cast<StyleCachedImageSet*>(m_imageSet.get()) : 0;
}
StyleImage* CSSImageSetValue::cachedOrPendingImageSet(Document* document)
{
if (!m_imageSet)
m_imageSet = StylePendingImage::create(this);
else if (document && !m_imageSet->isPendingImage()) {
float deviceScaleFactor = 1;
if (Page* page = document->page())
deviceScaleFactor = page->deviceScaleFactor();
if (deviceScaleFactor != m_scaleFactor) {
m_accessedBestFitImage = false;
m_imageSet = StylePendingImage::create(this);
}
}
return m_imageSet.get();
}
String CSSImageSetValue::customCssText() const
{
return "-webkit-image-set(" + CSSValueList::customCssText() + ")";
}
bool CSSImageSetValue::hasFailedOrCanceledSubresources() const
{
if (!m_imageSet || !m_imageSet->isCachedImageSet())
return false;
CachedResource* cachedResource = static_cast<StyleCachedImageSet*>(m_imageSet.get())->cachedImage();
if (!cachedResource)
return true;
return cachedResource->loadFailedOrCanceled();
}
CSSImageSetValue::CSSImageSetValue(const CSSImageSetValue& cloneFrom)
: CSSValueList(cloneFrom)
, m_accessedBestFitImage(false)
, m_scaleFactor(1)
{
}
PassRefPtr<CSSImageSetValue> CSSImageSetValue::cloneForCSSOM() const
{
return adoptRef(new CSSImageSetValue(*this));
}
}
#endif // ENABLE(CSS_IMAGE_SET)