mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 04:15:43 +00:00
Bug 781053 - Part 1 - Allow conversion of nsImageBoxFrame to an ImageLayer. r=roc
This commit is contained in:
parent
4c8fd0b349
commit
17610240f2
@ -14,7 +14,6 @@
|
||||
#include "nsCSSRendering.h"
|
||||
#include "nsCSSFrameConstructor.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "nsImageFrame.h"
|
||||
#include "nsRenderingContext.h"
|
||||
#include "MaskLayerImageCache.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
@ -335,7 +334,7 @@ protected:
|
||||
* Stores the pointer to the nsDisplayImage if we want to
|
||||
* convert this to an ImageLayer.
|
||||
*/
|
||||
nsDisplayImage* mImage;
|
||||
nsDisplayImageContainer* mImage;
|
||||
/**
|
||||
* Stores the clip that we need to apply to the image or, if there is no
|
||||
* image, a clip for SOME item in the layer. There is no guarantee which
|
||||
@ -1782,8 +1781,10 @@ ContainerState::ThebesLayerData::Accumulate(ContainerState* aState,
|
||||
/* Mark as available for conversion to image layer if this is a nsDisplayImage and
|
||||
* we are the first visible item in the ThebesLayerData object.
|
||||
*/
|
||||
if (mVisibleRegion.IsEmpty() && aItem->GetType() == nsDisplayItem::TYPE_IMAGE) {
|
||||
mImage = static_cast<nsDisplayImage*>(aItem);
|
||||
if (mVisibleRegion.IsEmpty() &&
|
||||
(aItem->GetType() == nsDisplayItem::TYPE_IMAGE ||
|
||||
aItem->GetType() == nsDisplayItem::TYPE_XUL_IMAGE)) {
|
||||
mImage = static_cast<nsDisplayImageContainer*>(aItem);
|
||||
} else {
|
||||
mImage = nullptr;
|
||||
}
|
||||
|
@ -2733,4 +2733,17 @@ public:
|
||||
nscoord mRightEdge; // length from the right side
|
||||
};
|
||||
|
||||
class nsDisplayImageContainer : public nsDisplayItem {
|
||||
public:
|
||||
typedef mozilla::layers::ImageContainer ImageContainer;
|
||||
typedef mozilla::layers::ImageLayer ImageLayer;
|
||||
|
||||
nsDisplayImageContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
|
||||
: nsDisplayItem(aBuilder, aFrame)
|
||||
{}
|
||||
|
||||
virtual already_AddRefed<ImageContainer> GetContainer() = 0;
|
||||
virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) = 0;
|
||||
};
|
||||
|
||||
#endif /*NSDISPLAYLIST_H_*/
|
||||
|
@ -362,15 +362,13 @@ public:
|
||||
* image itself, and hence receive events just as if the image itself
|
||||
* received events.
|
||||
*/
|
||||
class nsDisplayImage : public nsDisplayItem {
|
||||
class nsDisplayImage : public nsDisplayImageContainer {
|
||||
public:
|
||||
typedef mozilla::layers::ImageContainer ImageContainer;
|
||||
typedef mozilla::layers::ImageLayer ImageLayer;
|
||||
typedef mozilla::layers::LayerManager LayerManager;
|
||||
|
||||
nsDisplayImage(nsDisplayListBuilder* aBuilder, nsImageFrame* aFrame,
|
||||
imgIContainer* aImage)
|
||||
: nsDisplayItem(aBuilder, aFrame), mImage(aImage) {
|
||||
: nsDisplayImageContainer(aBuilder, aFrame), mImage(aImage) {
|
||||
MOZ_COUNT_CTOR(nsDisplayImage);
|
||||
}
|
||||
virtual ~nsDisplayImage() {
|
||||
@ -383,7 +381,7 @@ public:
|
||||
* Returns an ImageContainer for this image if the image type
|
||||
* supports it (TYPE_RASTER only).
|
||||
*/
|
||||
already_AddRefed<ImageContainer> GetContainer();
|
||||
virtual already_AddRefed<ImageContainer> GetContainer() MOZ_OVERRIDE;
|
||||
|
||||
gfxRect GetDestRect();
|
||||
|
||||
@ -399,7 +397,7 @@ public:
|
||||
* Configure an ImageLayer for this display item.
|
||||
* Set the required filter and scaling transform.
|
||||
*/
|
||||
void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset);
|
||||
virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) MOZ_OVERRIDE;
|
||||
|
||||
NS_DISPLAY_DECL_NAME("Image", TYPE_IMAGE)
|
||||
private:
|
||||
|
@ -44,11 +44,15 @@
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "ImageLayers.h"
|
||||
#include "ImageContainer.h"
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
#define ONLOAD_CALLED_TOO_EARLY 1
|
||||
|
||||
using namespace mozilla::layers;
|
||||
|
||||
class nsImageBoxFrameEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
@ -282,36 +286,6 @@ nsImageBoxFrame::UpdateLoadFlags()
|
||||
}
|
||||
}
|
||||
|
||||
class nsDisplayXULImage : public nsDisplayItem {
|
||||
public:
|
||||
nsDisplayXULImage(nsDisplayListBuilder* aBuilder,
|
||||
nsImageBoxFrame* aFrame) :
|
||||
nsDisplayItem(aBuilder, aFrame) {
|
||||
MOZ_COUNT_CTOR(nsDisplayXULImage);
|
||||
}
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
virtual ~nsDisplayXULImage() {
|
||||
MOZ_COUNT_DTOR(nsDisplayXULImage);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Doesn't handle HitTest because nsLeafBoxFrame already creates an
|
||||
// event receiver for us
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsRenderingContext* aCtx);
|
||||
NS_DISPLAY_DECL_NAME("XULImage", TYPE_XUL_IMAGE)
|
||||
};
|
||||
|
||||
void nsDisplayXULImage::Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsRenderingContext* aCtx)
|
||||
{
|
||||
static_cast<nsImageBoxFrame*>(mFrame)->
|
||||
PaintImage(*aCtx, mVisibleRect, ToReferenceFrame(),
|
||||
aBuilder->ShouldSyncDecodeImages()
|
||||
? (uint32_t) imgIContainer::FLAG_SYNC_DECODE
|
||||
: (uint32_t) imgIContainer::FLAG_NONE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImageBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsRect& aDirtyRect,
|
||||
@ -363,6 +337,74 @@ nsImageBoxFrame::PaintImage(nsRenderingContext& aRenderingContext,
|
||||
}
|
||||
}
|
||||
|
||||
void nsDisplayXULImage::Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsRenderingContext* aCtx)
|
||||
{
|
||||
static_cast<nsImageBoxFrame*>(mFrame)->
|
||||
PaintImage(*aCtx, mVisibleRect, ToReferenceFrame(),
|
||||
aBuilder->ShouldSyncDecodeImages()
|
||||
? (uint32_t) imgIContainer::FLAG_SYNC_DECODE
|
||||
: (uint32_t) imgIContainer::FLAG_NONE);
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayXULImage::ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset)
|
||||
{
|
||||
aLayer->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(mFrame));
|
||||
|
||||
int32_t factor = mFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
nsImageBoxFrame* imageFrame = static_cast<nsImageBoxFrame*>(mFrame);
|
||||
|
||||
nsRect dest;
|
||||
imageFrame->GetClientRect(dest);
|
||||
dest += ToReferenceFrame();
|
||||
gfxRect destRect(dest.x, dest.y, dest.width, dest.height);
|
||||
destRect.ScaleInverse(factor);
|
||||
|
||||
nsCOMPtr<imgIContainer> imgCon;
|
||||
imageFrame->mImageRequest->GetImage(getter_AddRefs(imgCon));
|
||||
int32_t imageWidth;
|
||||
int32_t imageHeight;
|
||||
imgCon->GetWidth(&imageWidth);
|
||||
imgCon->GetHeight(&imageHeight);
|
||||
|
||||
NS_ASSERTION(imageWidth != 0 && imageHeight != 0, "Invalid image size!");
|
||||
|
||||
gfxMatrix transform;
|
||||
transform.Translate(destRect.TopLeft() + aOffset);
|
||||
transform.Scale(destRect.Width()/imageWidth,
|
||||
destRect.Height()/imageHeight);
|
||||
aLayer->SetBaseTransform(gfx3DMatrix::From2D(transform));
|
||||
|
||||
aLayer->SetVisibleRegion(nsIntRect(0, 0, imageWidth, imageHeight));
|
||||
}
|
||||
|
||||
already_AddRefed<ImageContainer>
|
||||
nsDisplayXULImage::GetContainer()
|
||||
{
|
||||
return static_cast<nsImageBoxFrame*>(mFrame)->GetContainer();
|
||||
}
|
||||
|
||||
already_AddRefed<ImageContainer>
|
||||
nsImageBoxFrame::GetContainer()
|
||||
{
|
||||
bool hasSubRect = !mUseSrcAttr && (mSubRect.width > 0 || mSubRect.height > 0);
|
||||
if (hasSubRect || !mImageRequest) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIContainer> imgCon;
|
||||
mImageRequest->GetImage(getter_AddRefs(imgCon));
|
||||
if (!imgCon) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<ImageContainer> container;
|
||||
nsresult rv = imgCon->GetImageContainer(getter_AddRefs(container));
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
return container.forget();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// DidSetStyleContext
|
||||
|
@ -15,6 +15,8 @@
|
||||
|
||||
class nsImageBoxFrame;
|
||||
|
||||
class nsDisplayXULImage;
|
||||
|
||||
class nsImageBoxListener : public nsStubImageDecoderObserver
|
||||
{
|
||||
public:
|
||||
@ -43,6 +45,7 @@ private:
|
||||
class nsImageBoxFrame : public nsLeafBoxFrame
|
||||
{
|
||||
public:
|
||||
friend class nsDisplayXULImage;
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
|
||||
virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState);
|
||||
@ -103,6 +106,7 @@ public:
|
||||
const nsRect& aDirtyRect,
|
||||
nsPoint aPt, uint32_t aFlags);
|
||||
|
||||
already_AddRefed<mozilla::layers::ImageContainer> GetContainer();
|
||||
protected:
|
||||
nsImageBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext);
|
||||
|
||||
@ -127,4 +131,27 @@ private:
|
||||
bool mSuppressStyleCheck;
|
||||
}; // class nsImageBoxFrame
|
||||
|
||||
class nsDisplayXULImage : public nsDisplayImageContainer {
|
||||
public:
|
||||
nsDisplayXULImage(nsDisplayListBuilder* aBuilder,
|
||||
nsImageBoxFrame* aFrame) :
|
||||
nsDisplayImageContainer(aBuilder, aFrame) {
|
||||
MOZ_COUNT_CTOR(nsDisplayXULImage);
|
||||
}
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
virtual ~nsDisplayXULImage() {
|
||||
MOZ_COUNT_DTOR(nsDisplayXULImage);
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual already_AddRefed<ImageContainer> GetContainer() MOZ_OVERRIDE;
|
||||
virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) MOZ_OVERRIDE;
|
||||
|
||||
// Doesn't handle HitTest because nsLeafBoxFrame already creates an
|
||||
// event receiver for us
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsRenderingContext* aCtx);
|
||||
NS_DISPLAY_DECL_NAME("XULImage", TYPE_XUL_IMAGE)
|
||||
};
|
||||
|
||||
#endif /* nsImageBoxFrame_h___ */
|
||||
|
Loading…
Reference in New Issue
Block a user