void StyleResourceLoader::loadPendingImages(RenderStyle* style, ElementStyleResources& elementStyleResources) { if (elementStyleResources.pendingImageProperties().isEmpty()) return; PendingImagePropertyMap::const_iterator::Keys end = elementStyleResources.pendingImageProperties().end().keys(); for (PendingImagePropertyMap::const_iterator::Keys it = elementStyleResources.pendingImageProperties().begin().keys(); it != end; ++it) { CSSPropertyID currentProperty = *it; switch (currentProperty) { case CSSPropertyBackgroundImage: { for (FillLayer* backgroundLayer = &style->accessBackgroundLayers(); backgroundLayer; backgroundLayer = backgroundLayer->next()) { if (backgroundLayer->image() && backgroundLayer->image()->isPendingImage()) backgroundLayer->setImage(loadPendingImage(toStylePendingImage(backgroundLayer->image()), elementStyleResources.deviceScaleFactor())); } break; } case CSSPropertyCursor: { if (CursorList* cursorList = style->cursors()) { for (size_t i = 0; i < cursorList->size(); ++i) { CursorData& currentCursor = cursorList->at(i); if (StyleImage* image = currentCursor.image()) { if (image->isPendingImage()) currentCursor.setImage(loadPendingImage(toStylePendingImage(image), elementStyleResources.deviceScaleFactor())); } } } break; } case CSSPropertyListStyleImage: { if (style->listStyleImage() && style->listStyleImage()->isPendingImage()) style->setListStyleImage(loadPendingImage(toStylePendingImage(style->listStyleImage()), elementStyleResources.deviceScaleFactor())); break; } case CSSPropertyBorderImageSource: { if (style->borderImageSource() && style->borderImageSource()->isPendingImage()) style->setBorderImageSource(loadPendingImage(toStylePendingImage(style->borderImageSource()), elementStyleResources.deviceScaleFactor())); break; } case CSSPropertyWebkitMaskBoxImageSource: { if (style->maskBoxImageSource() && style->maskBoxImageSource()->isPendingImage()) style->setMaskBoxImageSource(loadPendingImage(toStylePendingImage(style->maskBoxImageSource()), elementStyleResources.deviceScaleFactor())); break; } case CSSPropertyWebkitMaskImage: { for (FillLayer* maskLayer = &style->accessMaskLayers(); maskLayer; maskLayer = maskLayer->next()) { if (maskLayer->image() && maskLayer->image()->isPendingImage()) maskLayer->setImage(loadPendingImage(toStylePendingImage(maskLayer->image()), elementStyleResources.deviceScaleFactor())); } break; } default: ASSERT_NOT_REACHED(); } } elementStyleResources.clearPendingImageProperties(); }
void StyleResourceLoader::loadPendingShaders(RenderStyle* style, const ElementStyleResources& elementStyleResources) { if (!style->hasFilter() || !elementStyleResources.hasPendingShaders()) return; Vector<RefPtr<FilterOperation> >& filterOperations = style->mutableFilter().operations(); for (unsigned i = 0; i < filterOperations.size(); ++i) { RefPtr<FilterOperation> filterOperation = filterOperations.at(i); if (filterOperation->getOperationType() == FilterOperation::CUSTOM) { CustomFilterOperation* customFilter = static_cast<CustomFilterOperation*>(filterOperation.get()); ASSERT(customFilter->program()); StyleCustomFilterProgram* program = static_cast<StyleCustomFilterProgram*>(customFilter->program()); // Note that the StylePendingShaders could be already resolved to StyleFetchedShaders. That's because the rule was matched before. // However, the StyleCustomFilterProgram that was initially created could have been removed from the cache in the meanwhile, // meaning that we get a new StyleCustomFilterProgram here that is not yet in the cache, but already has loaded StyleShaders. if (!program->hasPendingShaders() && program->inCache()) continue; RefPtr<StyleCustomFilterProgram> styleProgram = m_customFilterProgramCache->lookup(program); if (styleProgram.get()) { customFilter->setProgram(styleProgram.release()); } else { if (program->vertexShader() && program->vertexShader()->isPendingShader()) { CSSShaderValue* shaderValue = static_cast<StylePendingShader*>(program->vertexShader())->cssShaderValue(); program->setVertexShader(shaderValue->resource(m_fetcher)); } if (program->fragmentShader() && program->fragmentShader()->isPendingShader()) { CSSShaderValue* shaderValue = static_cast<StylePendingShader*>(program->fragmentShader())->cssShaderValue(); program->setFragmentShader(shaderValue->resource(m_fetcher)); } m_customFilterProgramCache->add(program); } } } }
void StyleResourceLoader::loadPendingSVGDocuments(RenderStyle* renderStyle, const ElementStyleResources& elementStyleResources) { if (!renderStyle->hasFilter() || elementStyleResources.pendingSVGDocuments().isEmpty()) return; Vector<RefPtr<FilterOperation> >& filterOperations = renderStyle->mutableFilter().operations(); for (unsigned i = 0; i < filterOperations.size(); ++i) { RefPtr<FilterOperation> filterOperation = filterOperations.at(i); if (filterOperation->getOperationType() == FilterOperation::REFERENCE) { ReferenceFilterOperation* referenceFilter = static_cast<ReferenceFilterOperation*>(filterOperation.get()); CSSSVGDocumentValue* value = elementStyleResources.pendingSVGDocuments().get(referenceFilter); if (!value) continue; DocumentResource* resource = value->load(m_fetcher); if (!resource) continue; // Stash the DocumentResource on the reference filter. referenceFilter->setDocumentResourceReference(adoptPtr(new DocumentResourceReference(resource))); } } }
void StyleResourceLoader::loadPendingResources(RenderStyle* renderStyle, ElementStyleResources& elementStyleResources) { // Start loading images referenced by this style. loadPendingImages(renderStyle, elementStyleResources); // Start loading the shaders referenced by this style. loadPendingShaders(renderStyle, elementStyleResources); // Start loading the SVG Documents referenced by this style. loadPendingSVGDocuments(renderStyle, elementStyleResources); // FIXME: Investigate if this clearing is necessary. elementStyleResources.clear(); }
void StyleResourceLoader::loadPendingImages(RenderStyle* style, const ElementStyleResources& elementStyleResources) { if (elementStyleResources.pendingImageProperties().isEmpty()) return; PendingImagePropertyMap::const_iterator::Keys end = elementStyleResources.pendingImageProperties().end().keys(); for (PendingImagePropertyMap::const_iterator::Keys it = elementStyleResources.pendingImageProperties().begin().keys(); it != end; ++it) { CSSPropertyID currentProperty = *it; switch (currentProperty) { case CSSPropertyBackgroundImage: { for (FillLayer* backgroundLayer = style->accessBackgroundLayers(); backgroundLayer; backgroundLayer = backgroundLayer->next()) { if (backgroundLayer->image() && backgroundLayer->image()->isPendingImage()) backgroundLayer->setImage(loadPendingImage(static_cast<StylePendingImage*>(backgroundLayer->image()), elementStyleResources.deviceScaleFactor())); } break; } case CSSPropertyContent: { for (ContentData* contentData = const_cast<ContentData*>(style->contentData()); contentData; contentData = contentData->next()) { if (contentData->isImage()) { StyleImage* image = static_cast<ImageContentData*>(contentData)->image(); if (image->isPendingImage()) { RefPtr<StyleImage> loadedImage = loadPendingImage(static_cast<StylePendingImage*>(image), elementStyleResources.deviceScaleFactor()); if (loadedImage) static_cast<ImageContentData*>(contentData)->setImage(loadedImage.release()); } } } break; } case CSSPropertyCursor: { if (CursorList* cursorList = style->cursors()) { for (size_t i = 0; i < cursorList->size(); ++i) { CursorData& currentCursor = cursorList->at(i); if (StyleImage* image = currentCursor.image()) { if (image->isPendingImage()) currentCursor.setImage(loadPendingImage(static_cast<StylePendingImage*>(image), elementStyleResources.deviceScaleFactor())); } } } break; } case CSSPropertyListStyleImage: { if (style->listStyleImage() && style->listStyleImage()->isPendingImage()) style->setListStyleImage(loadPendingImage(static_cast<StylePendingImage*>(style->listStyleImage()), elementStyleResources.deviceScaleFactor())); break; } case CSSPropertyBorderImageSource: { if (style->borderImageSource() && style->borderImageSource()->isPendingImage()) style->setBorderImageSource(loadPendingImage(static_cast<StylePendingImage*>(style->borderImageSource()), elementStyleResources.deviceScaleFactor())); break; } case CSSPropertyWebkitBoxReflect: { if (StyleReflection* reflection = style->boxReflect()) { const NinePieceImage& maskImage = reflection->mask(); if (maskImage.image() && maskImage.image()->isPendingImage()) { RefPtr<StyleImage> loadedImage = loadPendingImage(static_cast<StylePendingImage*>(maskImage.image()), elementStyleResources.deviceScaleFactor()); reflection->setMask(NinePieceImage(loadedImage.release(), maskImage.imageSlices(), maskImage.fill(), maskImage.borderSlices(), maskImage.outset(), maskImage.horizontalRule(), maskImage.verticalRule())); } } break; } case CSSPropertyWebkitMaskBoxImageSource: { if (style->maskBoxImageSource() && style->maskBoxImageSource()->isPendingImage()) style->setMaskBoxImageSource(loadPendingImage(static_cast<StylePendingImage*>(style->maskBoxImageSource()), elementStyleResources.deviceScaleFactor())); break; } case CSSPropertyWebkitMaskImage: { for (FillLayer* maskLayer = style->accessMaskLayers(); maskLayer; maskLayer = maskLayer->next()) { if (maskLayer->image() && maskLayer->image()->isPendingImage()) maskLayer->setImage(loadPendingImage(static_cast<StylePendingImage*>(maskLayer->image()), elementStyleResources.deviceScaleFactor())); } break; } case CSSPropertyWebkitShapeInside: loadPendingShapeImage(style, style->shapeInside()); break; case CSSPropertyWebkitShapeOutside: loadPendingShapeImage(style, style->shapeOutside()); break; default: ASSERT_NOT_REACHED(); } } }