зеркало из https://github.com/mozilla/pjs.git
Bug 507817: BorderImage should not call ExtractCurrentFrame each time it draws [r=dbaron r=joedrew]
This commit is contained in:
Родитель
d305b5ffae
Коммит
013b393bf3
|
@ -364,7 +364,7 @@ static void DrawBorderImage(nsPresContext* aPresContext,
|
||||||
nsIRenderingContext& aRenderingContext,
|
nsIRenderingContext& aRenderingContext,
|
||||||
nsIFrame* aForFrame,
|
nsIFrame* aForFrame,
|
||||||
const nsRect& aBorderArea,
|
const nsRect& aBorderArea,
|
||||||
const nsStyleBorder& aBorderStyle,
|
const nsStyleBorder& aStyleBorder,
|
||||||
const nsRect& aDirtyRect);
|
const nsRect& aDirtyRect);
|
||||||
|
|
||||||
static void DrawBorderImageComponent(nsIRenderingContext& aRenderingContext,
|
static void DrawBorderImageComponent(nsIRenderingContext& aRenderingContext,
|
||||||
|
@ -375,7 +375,9 @@ static void DrawBorderImageComponent(nsIRenderingContext& aRenderingContext,
|
||||||
const nsIntRect& aSrc,
|
const nsIntRect& aSrc,
|
||||||
PRUint8 aHFill,
|
PRUint8 aHFill,
|
||||||
PRUint8 aVFill,
|
PRUint8 aVFill,
|
||||||
const nsSize& aUnitSize);
|
const nsSize& aUnitSize,
|
||||||
|
const nsStyleBorder& aStyleBorder,
|
||||||
|
PRUint8 aIndex);
|
||||||
|
|
||||||
static nscolor MakeBevelColor(PRIntn whichSide, PRUint8 style,
|
static nscolor MakeBevelColor(PRIntn whichSide, PRUint8 style,
|
||||||
nscolor aBackgroundColor,
|
nscolor aBackgroundColor,
|
||||||
|
@ -544,7 +546,7 @@ nsCSSRendering::PaintBorder(nsPresContext* aPresContext,
|
||||||
nsIFrame* aForFrame,
|
nsIFrame* aForFrame,
|
||||||
const nsRect& aDirtyRect,
|
const nsRect& aDirtyRect,
|
||||||
const nsRect& aBorderArea,
|
const nsRect& aBorderArea,
|
||||||
const nsStyleBorder& aBorderStyle,
|
const nsStyleBorder& aStyleBorder,
|
||||||
nsStyleContext* aStyleContext,
|
nsStyleContext* aStyleContext,
|
||||||
PRIntn aSkipSides)
|
PRIntn aSkipSides)
|
||||||
{
|
{
|
||||||
|
@ -564,9 +566,9 @@ nsCSSRendering::PaintBorder(nsPresContext* aPresContext,
|
||||||
return; // Let the theme handle it.
|
return; // Let the theme handle it.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aBorderStyle.IsBorderImageLoaded()) {
|
if (aStyleBorder.IsBorderImageLoaded()) {
|
||||||
DrawBorderImage(aPresContext, aRenderingContext, aForFrame,
|
DrawBorderImage(aPresContext, aRenderingContext, aForFrame,
|
||||||
aBorderArea, aBorderStyle, aDirtyRect);
|
aBorderArea, aStyleBorder, aDirtyRect);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,14 +581,14 @@ nsCSSRendering::PaintBorder(nsPresContext* aPresContext,
|
||||||
(aStyleContext, compatMode == eCompatibility_NavQuirks ? PR_TRUE : PR_FALSE);
|
(aStyleContext, compatMode == eCompatibility_NavQuirks ? PR_TRUE : PR_FALSE);
|
||||||
const nsStyleBackground* bgColor = bgContext->GetStyleBackground();
|
const nsStyleBackground* bgColor = bgContext->GetStyleBackground();
|
||||||
|
|
||||||
border = aBorderStyle.GetComputedBorder();
|
border = aStyleBorder.GetComputedBorder();
|
||||||
if ((0 == border.left) && (0 == border.right) &&
|
if ((0 == border.left) && (0 == border.right) &&
|
||||||
(0 == border.top) && (0 == border.bottom)) {
|
(0 == border.top) && (0 == border.bottom)) {
|
||||||
// Empty border area
|
// Empty border area
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GetBorderRadiusTwips(aBorderStyle.mBorderRadius, aForFrame->GetSize().width,
|
GetBorderRadiusTwips(aStyleBorder.mBorderRadius, aForFrame->GetSize().width,
|
||||||
twipsRadii);
|
twipsRadii);
|
||||||
|
|
||||||
// Turn off rendering for all of the zero sized sides
|
// Turn off rendering for all of the zero sized sides
|
||||||
|
@ -626,9 +628,9 @@ nsCSSRendering::PaintBorder(nsPresContext* aPresContext,
|
||||||
// pull out styles, colors, composite colors
|
// pull out styles, colors, composite colors
|
||||||
NS_FOR_CSS_SIDES (i) {
|
NS_FOR_CSS_SIDES (i) {
|
||||||
PRBool foreground;
|
PRBool foreground;
|
||||||
borderStyles[i] = aBorderStyle.GetBorderStyle(i);
|
borderStyles[i] = aStyleBorder.GetBorderStyle(i);
|
||||||
aBorderStyle.GetBorderColor(i, borderColors[i], foreground);
|
aStyleBorder.GetBorderColor(i, borderColors[i], foreground);
|
||||||
aBorderStyle.GetCompositeColors(i, &compositeColors[i]);
|
aStyleBorder.GetCompositeColors(i, &compositeColors[i]);
|
||||||
|
|
||||||
if (foreground)
|
if (foreground)
|
||||||
borderColors[i] = ourColor->mColor;
|
borderColors[i] = ourColor->mColor;
|
||||||
|
@ -685,7 +687,7 @@ nsCSSRendering::PaintOutline(nsPresContext* aPresContext,
|
||||||
nsIFrame* aForFrame,
|
nsIFrame* aForFrame,
|
||||||
const nsRect& aDirtyRect,
|
const nsRect& aDirtyRect,
|
||||||
const nsRect& aBorderArea,
|
const nsRect& aBorderArea,
|
||||||
const nsStyleBorder& aBorderStyle,
|
const nsStyleBorder& aStyleBorder,
|
||||||
const nsStyleOutline& aOutlineStyle,
|
const nsStyleOutline& aOutlineStyle,
|
||||||
nsStyleContext* aStyleContext)
|
nsStyleContext* aStyleContext)
|
||||||
{
|
{
|
||||||
|
@ -2484,7 +2486,7 @@ DrawBorderImage(nsPresContext* aPresContext,
|
||||||
nsIRenderingContext& aRenderingContext,
|
nsIRenderingContext& aRenderingContext,
|
||||||
nsIFrame* aForFrame,
|
nsIFrame* aForFrame,
|
||||||
const nsRect& aBorderArea,
|
const nsRect& aBorderArea,
|
||||||
const nsStyleBorder& aBorderStyle,
|
const nsStyleBorder& aStyleBorder,
|
||||||
const nsRect& aDirtyRect)
|
const nsRect& aDirtyRect)
|
||||||
{
|
{
|
||||||
if (aDirtyRect.IsEmpty())
|
if (aDirtyRect.IsEmpty())
|
||||||
|
@ -2496,9 +2498,9 @@ DrawBorderImage(nsPresContext* aPresContext,
|
||||||
// XXX We shouldn't really... since if anybody is passing in a
|
// XXX We shouldn't really... since if anybody is passing in a
|
||||||
// different style, they'll potentially have the wrong size for the
|
// different style, they'll potentially have the wrong size for the
|
||||||
// border too.
|
// border too.
|
||||||
aPresContext->SetupBorderImageLoaders(aForFrame, &aBorderStyle);
|
aPresContext->SetupBorderImageLoaders(aForFrame, &aStyleBorder);
|
||||||
|
|
||||||
imgIRequest *req = aBorderStyle.GetBorderImage();
|
imgIRequest *req = aStyleBorder.GetBorderImage();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
{
|
{
|
||||||
|
@ -2525,7 +2527,7 @@ DrawBorderImage(nsPresContext* aPresContext,
|
||||||
// Convert percentages and clamp values to the image size.
|
// Convert percentages and clamp values to the image size.
|
||||||
nsIntMargin split;
|
nsIntMargin split;
|
||||||
NS_FOR_CSS_SIDES(s) {
|
NS_FOR_CSS_SIDES(s) {
|
||||||
nsStyleCoord coord = aBorderStyle.mBorderImageSplit.Get(s);
|
nsStyleCoord coord = aStyleBorder.mBorderImageSplit.Get(s);
|
||||||
PRInt32 imgDimension = ((s == NS_SIDE_TOP || s == NS_SIDE_BOTTOM)
|
PRInt32 imgDimension = ((s == NS_SIDE_TOP || s == NS_SIDE_BOTTOM)
|
||||||
? imageSize.height
|
? imageSize.height
|
||||||
: imageSize.width);
|
: imageSize.width);
|
||||||
|
@ -2550,7 +2552,7 @@ DrawBorderImage(nsPresContext* aPresContext,
|
||||||
split.side(s) = NS_lround(value);
|
split.side(s) = NS_lround(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsMargin border(aBorderStyle.GetActualBorder());
|
nsMargin border(aStyleBorder.GetActualBorder());
|
||||||
|
|
||||||
// These helper tables recharacterize the 'split' and 'border' margins
|
// These helper tables recharacterize the 'split' and 'border' margins
|
||||||
// in a more convenient form: they are the x/y/width/height coords
|
// in a more convenient form: they are the x/y/width/height coords
|
||||||
|
@ -2642,8 +2644,8 @@ DrawBorderImage(nsPresContext* aPresContext,
|
||||||
|
|
||||||
unitSize.width = splitWidth[i]*hFactor;
|
unitSize.width = splitWidth[i]*hFactor;
|
||||||
unitSize.height = splitHeight[j]*vFactor;
|
unitSize.height = splitHeight[j]*vFactor;
|
||||||
fillStyleH = aBorderStyle.mBorderImageHFill;
|
fillStyleH = aStyleBorder.mBorderImageHFill;
|
||||||
fillStyleV = aBorderStyle.mBorderImageVFill;
|
fillStyleV = aStyleBorder.mBorderImageVFill;
|
||||||
|
|
||||||
} else if (i == MIDDLE) { // top, bottom
|
} else if (i == MIDDLE) { // top, bottom
|
||||||
// Sides are always stretched to the thickness of their border,
|
// Sides are always stretched to the thickness of their border,
|
||||||
|
@ -2656,7 +2658,7 @@ DrawBorderImage(nsPresContext* aPresContext,
|
||||||
|
|
||||||
unitSize.width = splitWidth[i]*factor;
|
unitSize.width = splitWidth[i]*factor;
|
||||||
unitSize.height = borderHeight[j];
|
unitSize.height = borderHeight[j];
|
||||||
fillStyleH = aBorderStyle.mBorderImageHFill;
|
fillStyleH = aStyleBorder.mBorderImageHFill;
|
||||||
fillStyleV = NS_STYLE_BORDER_IMAGE_STRETCH;
|
fillStyleV = NS_STYLE_BORDER_IMAGE_STRETCH;
|
||||||
|
|
||||||
} else if (j == MIDDLE) { // left, right
|
} else if (j == MIDDLE) { // left, right
|
||||||
|
@ -2669,7 +2671,7 @@ DrawBorderImage(nsPresContext* aPresContext,
|
||||||
unitSize.width = borderWidth[i];
|
unitSize.width = borderWidth[i];
|
||||||
unitSize.height = splitHeight[j]*factor;
|
unitSize.height = splitHeight[j]*factor;
|
||||||
fillStyleH = NS_STYLE_BORDER_IMAGE_STRETCH;
|
fillStyleH = NS_STYLE_BORDER_IMAGE_STRETCH;
|
||||||
fillStyleV = aBorderStyle.mBorderImageVFill;
|
fillStyleV = aStyleBorder.mBorderImageVFill;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Corners are always stretched to fit the corner.
|
// Corners are always stretched to fit the corner.
|
||||||
|
@ -2682,7 +2684,8 @@ DrawBorderImage(nsPresContext* aPresContext,
|
||||||
DrawBorderImageComponent(aRenderingContext, aForFrame,
|
DrawBorderImageComponent(aRenderingContext, aForFrame,
|
||||||
imgContainer, aDirtyRect,
|
imgContainer, aDirtyRect,
|
||||||
destArea, subArea,
|
destArea, subArea,
|
||||||
fillStyleH, fillStyleV, unitSize);
|
fillStyleH, fillStyleV,
|
||||||
|
unitSize, aStyleBorder, i * (RIGHT + 1) + j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2696,16 +2699,28 @@ DrawBorderImageComponent(nsIRenderingContext& aRenderingContext,
|
||||||
const nsIntRect& aSrc,
|
const nsIntRect& aSrc,
|
||||||
PRUint8 aHFill,
|
PRUint8 aHFill,
|
||||||
PRUint8 aVFill,
|
PRUint8 aVFill,
|
||||||
const nsSize& aUnitSize)
|
const nsSize& aUnitSize,
|
||||||
|
const nsStyleBorder& aStyleBorder,
|
||||||
|
PRUint8 aIndex)
|
||||||
{
|
{
|
||||||
if (aFill.IsEmpty() || aSrc.IsEmpty())
|
if (aFill.IsEmpty() || aSrc.IsEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Don't bother trying to cache sub images if the border image is animated
|
||||||
|
// We can only sucessfully call GetAnimated() if we are fully decoded, so default to PR_TRUE
|
||||||
|
PRBool animated = PR_TRUE;
|
||||||
|
aImage->GetAnimated(&animated);
|
||||||
|
|
||||||
nsCOMPtr<imgIContainer> subImage;
|
nsCOMPtr<imgIContainer> subImage;
|
||||||
if (NS_FAILED(aImage->ExtractFrame(imgIContainer::FRAME_CURRENT, aSrc,
|
if (animated || (subImage = aStyleBorder.GetSubImage(aIndex)) == 0) {
|
||||||
imgIContainer::FLAG_SYNC_DECODE,
|
if (NS_FAILED(aImage->ExtractFrame(imgIContainer::FRAME_CURRENT, aSrc,
|
||||||
getter_AddRefs(subImage))))
|
imgIContainer::FLAG_SYNC_DECODE,
|
||||||
return;
|
getter_AddRefs(subImage))))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!animated)
|
||||||
|
aStyleBorder.SetSubImage(aIndex, subImage);
|
||||||
|
}
|
||||||
|
|
||||||
gfxPattern::GraphicsFilter graphicsFilter =
|
gfxPattern::GraphicsFilter graphicsFilter =
|
||||||
nsLayoutUtils::GetGraphicsFilterForFrame(aForFrame);
|
nsLayoutUtils::GetGraphicsFilterForFrame(aForFrame);
|
||||||
|
|
|
@ -69,6 +69,7 @@
|
||||||
|
|
||||||
class nsIFrame;
|
class nsIFrame;
|
||||||
class imgIRequest;
|
class imgIRequest;
|
||||||
|
class imgIContainer;
|
||||||
|
|
||||||
// Includes nsStyleStructID.
|
// Includes nsStyleStructID.
|
||||||
#include "nsStyleStructFwd.h"
|
#include "nsStyleStructFwd.h"
|
||||||
|
@ -838,6 +839,11 @@ struct nsStyleBorder {
|
||||||
inline void SetBorderImage(imgIRequest* aImage);
|
inline void SetBorderImage(imgIRequest* aImage);
|
||||||
inline imgIRequest* GetBorderImage() const;
|
inline imgIRequest* GetBorderImage() const;
|
||||||
|
|
||||||
|
// These methods are used for the caller to caches the sub images created during
|
||||||
|
// a border-image paint operation
|
||||||
|
inline void SetSubImage(PRUint8 aIndex, imgIContainer* aSubImage) const;
|
||||||
|
inline imgIContainer* GetSubImage(PRUint8 aIndex) const;
|
||||||
|
|
||||||
void GetCompositeColors(PRInt32 aIndex, nsBorderColors** aColors) const
|
void GetCompositeColors(PRInt32 aIndex, nsBorderColors** aColors) const
|
||||||
{
|
{
|
||||||
if (!mBorderColors)
|
if (!mBorderColors)
|
||||||
|
@ -897,6 +903,9 @@ protected:
|
||||||
|
|
||||||
nsCOMPtr<imgIRequest> mBorderImage; // [reset]
|
nsCOMPtr<imgIRequest> mBorderImage; // [reset]
|
||||||
|
|
||||||
|
// Cache used by callers for border-image painting
|
||||||
|
nsCOMArray<imgIContainer> mSubImages;
|
||||||
|
|
||||||
nscoord mTwipsPerPixel;
|
nscoord mTwipsPerPixel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -46,11 +46,13 @@
|
||||||
|
|
||||||
#include "nsStyleStruct.h"
|
#include "nsStyleStruct.h"
|
||||||
#include "imgIRequest.h"
|
#include "imgIRequest.h"
|
||||||
|
#include "imgIContainer.h"
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
nsStyleBorder::SetBorderImage(imgIRequest* aImage)
|
nsStyleBorder::SetBorderImage(imgIRequest* aImage)
|
||||||
{
|
{
|
||||||
mBorderImage = aImage;
|
mBorderImage = aImage;
|
||||||
|
mSubImages.Clear();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Request a decode to jump start decoding, and lock it to make sure it
|
* Request a decode to jump start decoding, and lock it to make sure it
|
||||||
|
@ -76,4 +78,19 @@ inline PRBool nsStyleBorder::IsBorderImageLoaded() const
|
||||||
(status & imgIRequest::STATUS_LOAD_COMPLETE);
|
(status & imgIRequest::STATUS_LOAD_COMPLETE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
nsStyleBorder::SetSubImage(PRUint8 aIndex, imgIContainer* aSubImage) const
|
||||||
|
{
|
||||||
|
const_cast<nsStyleBorder*>(this)->mSubImages.ReplaceObjectAt(aSubImage, aIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline imgIContainer*
|
||||||
|
nsStyleBorder::GetSubImage(PRUint8 aIndex) const
|
||||||
|
{
|
||||||
|
imgIContainer* subImage = 0;
|
||||||
|
if (0 <= aIndex && mSubImages.Count() > aIndex)
|
||||||
|
subImage = mSubImages[aIndex];
|
||||||
|
return subImage;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !defined(nsStyleStructInlines_h_) */
|
#endif /* !defined(nsStyleStructInlines_h_) */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче