зеркало из https://github.com/mozilla/pjs.git
Bug 430450 – vertical stripes in windowless plugins.
Snap to pixels and round dirty rect out. r+sr=roc
This commit is contained in:
Родитель
7eb29eb768
Коммит
97d7e0a66f
|
@ -362,8 +362,9 @@ public:
|
|||
#elif defined(XP_MACOSX)
|
||||
void Paint(const nsRect& aDirtyRect);
|
||||
#elif defined(MOZ_X11)
|
||||
void Paint(nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect);
|
||||
void Paint(gfxContext* aContext,
|
||||
const gfxRect& aFrameRect,
|
||||
const gfxRect& aDirtyRect);
|
||||
#elif defined(XP_OS2)
|
||||
void Paint(const nsRect& aDirtyRect, HPS aHPS);
|
||||
#endif
|
||||
|
@ -480,8 +481,9 @@ private:
|
|||
class Renderer : public gfxXlibNativeRenderer {
|
||||
public:
|
||||
Renderer(nsPluginWindow* aWindow, nsIPluginInstance* aInstance,
|
||||
const nsIntRect& aDirtyRect)
|
||||
: mWindow(aWindow), mInstance(aInstance), mDirtyRect(aDirtyRect)
|
||||
const nsIntSize& aPluginSize, const nsIntRect& aDirtyRect)
|
||||
: mWindow(aWindow), mInstance(aInstance),
|
||||
mPluginSize(aPluginSize), mDirtyRect(aDirtyRect)
|
||||
{}
|
||||
virtual nsresult NativeDraw(Display* dpy, Drawable drawable, Visual* visual,
|
||||
short offsetX, short offsetY,
|
||||
|
@ -489,13 +491,14 @@ private:
|
|||
private:
|
||||
nsPluginWindow* mWindow;
|
||||
nsIPluginInstance* mInstance;
|
||||
const nsIntSize& mPluginSize;
|
||||
const nsIntRect& mDirtyRect;
|
||||
};
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#if defined(XP_WIN) || (defined(DO_DIRTY_INTERSECT) && defined(XP_MACOSX)) || defined(MOZ_X11) || defined(XP_OS2)
|
||||
#if defined(XP_WIN) || (defined(DO_DIRTY_INTERSECT) && defined(XP_MACOSX)) || defined(XP_OS2)
|
||||
static void ConvertAppUnitsToPixels(const nsPresContext& aPresContext, const nsRect& aTwipsRect, nsIntRect& aPixelRect);
|
||||
#endif
|
||||
|
||||
|
@ -1082,23 +1085,20 @@ nsObjectFrame::DidReflow(nsPresContext* aPresContext,
|
|||
return rv;
|
||||
}
|
||||
|
||||
static void PaintPrintPlugin(nsIFrame* aFrame, nsIRenderingContext* aCtx,
|
||||
const nsRect& aDirtyRect, nsPoint aPt)
|
||||
/* static */ void
|
||||
nsObjectFrame::PaintPrintPlugin(nsIFrame* aFrame, nsIRenderingContext* aCtx,
|
||||
const nsRect& aDirtyRect, nsPoint aPt)
|
||||
{
|
||||
// FIXME - Bug 385435: Doesn't aDirtyRect need translating too?
|
||||
nsIRenderingContext::AutoPushTranslation translate(aCtx, aPt.x, aPt.y);
|
||||
static_cast<nsObjectFrame*>(aFrame)->PrintPlugin(*aCtx, aDirtyRect);
|
||||
}
|
||||
|
||||
static void PaintPlugin(nsIFrame* aFrame, nsIRenderingContext* aCtx,
|
||||
const nsRect& aDirtyRect, nsPoint aPt)
|
||||
/*static */ void
|
||||
nsObjectFrame::PaintPlugin(nsIFrame* aFrame, nsIRenderingContext* aCtx,
|
||||
const nsRect& aDirtyRect, nsPoint aPt)
|
||||
{
|
||||
nsIRenderingContext::AutoPushTranslation translate(aCtx, aPt.x, aPt.y);
|
||||
#ifdef MOZ_X11 // FIXME - Bug 385435: Don't others want this too!
|
||||
nsRect relativeDirtyRect = aDirtyRect - aPt;
|
||||
static_cast<nsObjectFrame*>(aFrame)->PaintPlugin(*aCtx, relativeDirtyRect);
|
||||
#else
|
||||
static_cast<nsObjectFrame*>(aFrame)->PaintPlugin(*aCtx, aDirtyRect);
|
||||
#endif
|
||||
static_cast<nsObjectFrame*>(aFrame)->PaintPlugin(*aCtx, aDirtyRect, aPt);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1127,7 +1127,7 @@ nsObjectFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
nsDisplayGeneric(this, PaintPrintPlugin, "PrintPlugin"));
|
||||
|
||||
return aLists.Content()->AppendNewToTop(new (aBuilder)
|
||||
nsDisplayGeneric(this, ::PaintPlugin, "Plugin"));
|
||||
nsDisplayGeneric(this, PaintPlugin, "Plugin"));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1343,12 +1343,15 @@ nsObjectFrame::PrintPlugin(nsIRenderingContext& aRenderingContext,
|
|||
|
||||
void
|
||||
nsObjectFrame::PaintPlugin(nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect)
|
||||
const nsRect& aDirtyRect, const nsPoint& aFramePt)
|
||||
{
|
||||
// Screen painting code
|
||||
#if defined(XP_MACOSX)
|
||||
// delegate all painting to the plugin instance.
|
||||
if (mInstanceOwner) {
|
||||
// FIXME - Bug 385435: Doesn't aDirtyRect need translating too?
|
||||
nsIRenderingContext::AutoPushTranslation translate(aCtx, aPt.x, aPt.y);
|
||||
|
||||
if (mInstanceOwner->GetDrawingModel() == NPDrawingModelCoreGraphics) {
|
||||
PRInt32 p2a = PresContext()->AppUnitsPerDevPixel();
|
||||
gfxRect nativeClipRect(aDirtyRect.x, aDirtyRect.y,
|
||||
|
@ -1398,8 +1401,15 @@ nsObjectFrame::PaintPlugin(nsIRenderingContext& aRenderingContext,
|
|||
nsPluginWindow * window;
|
||||
mInstanceOwner->GetWindow(window);
|
||||
|
||||
if (window->type == nsPluginWindowType_Drawable)
|
||||
mInstanceOwner->Paint(aRenderingContext, aDirtyRect);
|
||||
if (window->type == nsPluginWindowType_Drawable) {
|
||||
gfxRect frameGfxRect =
|
||||
PresContext()->AppUnitsToGfxUnits(nsRect(aFramePt, GetSize()));
|
||||
gfxRect dirtyGfxRect =
|
||||
PresContext()->AppUnitsToGfxUnits(aDirtyRect);
|
||||
gfxContext* ctx = aRenderingContext.ThebesContext();
|
||||
|
||||
mInstanceOwner->Paint(ctx, frameGfxRect, dirtyGfxRect);
|
||||
}
|
||||
}
|
||||
#elif defined (XP_WIN) || defined(XP_OS2)
|
||||
nsCOMPtr<nsIPluginInstance> inst;
|
||||
|
@ -1410,6 +1420,9 @@ nsObjectFrame::PaintPlugin(nsIRenderingContext& aRenderingContext,
|
|||
mInstanceOwner->GetWindow(window);
|
||||
|
||||
if (window->type == nsPluginWindowType_Drawable) {
|
||||
// FIXME - Bug 385435: Doesn't aDirtyRect need translating too?
|
||||
nsIRenderingContext::AutoPushTranslation translate(aCtx, aPt.x, aPt.y);
|
||||
|
||||
// check if we need to call SetWindow with updated parameters
|
||||
PRBool doupdatewindow = PR_FALSE;
|
||||
// the offset of the DC
|
||||
|
@ -1769,6 +1782,7 @@ private:
|
|||
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsStopPluginRunnable, nsRunnable, nsITimerCallback)
|
||||
|
||||
#ifdef XP_WIN
|
||||
static const char*
|
||||
GetMIMEType(nsIPluginInstance *aPluginInstance)
|
||||
{
|
||||
|
@ -1781,6 +1795,7 @@ GetMIMEType(nsIPluginInstance *aPluginInstance)
|
|||
}
|
||||
return "";
|
||||
}
|
||||
#endif
|
||||
|
||||
static PRBool
|
||||
MatchPluginName(nsPluginInstanceOwner *aInstanceOwner, const char *aPluginName)
|
||||
|
@ -4052,25 +4067,52 @@ void nsPluginInstanceOwner::Paint(const nsRect& aDirtyRect, HPS aHPS)
|
|||
#endif
|
||||
|
||||
#ifdef MOZ_X11
|
||||
void nsPluginInstanceOwner::Paint(nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect)
|
||||
void nsPluginInstanceOwner::Paint(gfxContext* aContext,
|
||||
const gfxRect& aFrameRect,
|
||||
const gfxRect& aDirtyRect)
|
||||
{
|
||||
if (!mInstance || !mOwner)
|
||||
return;
|
||||
|
||||
|
||||
// Align to device pixels where sensible
|
||||
// to provide crisper and faster drawing.
|
||||
gfxRect pluginRect = aFrameRect;
|
||||
if (aContext->UserToDevicePixelSnapped(pluginRect)) {
|
||||
pluginRect = aContext->DeviceToUser(pluginRect);
|
||||
}
|
||||
|
||||
// Round out the dirty rect to plugin pixels to ensure the plugin draws
|
||||
// enough pixels for interpolation to device pixels.
|
||||
gfxRect dirtyRect = aDirtyRect + -pluginRect.pos;
|
||||
dirtyRect.RoundOut();
|
||||
|
||||
// Plugins can only draw an integer number of pixels.
|
||||
//
|
||||
// With translation-only transformation matrices, pluginRect is already
|
||||
// pixel-aligned.
|
||||
//
|
||||
// With more complex transformations, modifying the scales in the
|
||||
// transformation matrix could retain subpixel accuracy and let the plugin
|
||||
// draw a suitable number of pixels for interpolation to device pixels in
|
||||
// Renderer::Draw, but such cases are not common enough to warrant the
|
||||
// effort now.
|
||||
nsIntSize pluginSize(NS_lround(pluginRect.size.width),
|
||||
NS_lround(pluginRect.size.height));
|
||||
|
||||
// Determine what the plugin needs to draw.
|
||||
nsIntRect pluginDirtyRect(PRInt32(dirtyRect.pos.x),
|
||||
PRInt32(dirtyRect.pos.y),
|
||||
PRInt32(dirtyRect.size.width),
|
||||
PRInt32(dirtyRect.size.height));
|
||||
if (!pluginDirtyRect.
|
||||
IntersectRect(nsIntRect(0, 0, pluginSize.width, pluginSize.height),
|
||||
pluginDirtyRect))
|
||||
return;
|
||||
|
||||
nsPluginWindow* window;
|
||||
GetWindow(window);
|
||||
|
||||
nsIntRect dirtyRectInPixels;
|
||||
ConvertAppUnitsToPixels(*mOwner->PresContext(), aDirtyRect,
|
||||
dirtyRectInPixels);
|
||||
// Sanitize the dirty rect so we don't tell plugins that the area outside
|
||||
// the plugin rectangle needs updating.
|
||||
nsIntRect pluginDirtyRect;
|
||||
if (!pluginDirtyRect.IntersectRect(nsIntRect(0, 0, window->width, window->height), dirtyRectInPixels))
|
||||
return;
|
||||
|
||||
Renderer renderer(window, mInstance, pluginDirtyRect);
|
||||
Renderer renderer(window, mInstance, pluginSize, pluginDirtyRect);
|
||||
PRUint32 rendererFlags =
|
||||
Renderer::DRAW_SUPPORTS_OFFSET |
|
||||
Renderer::DRAW_SUPPORTS_CLIP_RECT |
|
||||
|
@ -4083,9 +4125,9 @@ void nsPluginInstanceOwner::Paint(nsIRenderingContext& aRenderingContext,
|
|||
if (!transparent)
|
||||
rendererFlags |= Renderer::DRAW_IS_OPAQUE;
|
||||
|
||||
gfxContext* ctx =
|
||||
static_cast<gfxContext*>
|
||||
(aRenderingContext.GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT));
|
||||
// Renderer::Draw() draws a rectangle with top-left at the aContext origin.
|
||||
gfxContextAutoSaveRestore autoSR(aContext);
|
||||
aContext->Translate(pluginRect.pos);
|
||||
|
||||
// The display used by gfxXlibNativeRenderer will be the one for the cairo
|
||||
// surface (provided that it is an Xlib surface) but the display argument
|
||||
|
@ -4093,7 +4135,7 @@ void nsPluginInstanceOwner::Paint(nsIRenderingContext& aRenderingContext,
|
|||
// _create_temp_xlib_surface -> DefaultScreen(dpy).
|
||||
NPSetWindowCallbackStruct* ws_info =
|
||||
static_cast<NPSetWindowCallbackStruct*>(window->ws_info);
|
||||
renderer.Draw(ws_info->display, ctx, window->width, window->height,
|
||||
renderer.Draw(ws_info->display, aContext, pluginSize.width, pluginSize.height,
|
||||
rendererFlags, nsnull);
|
||||
}
|
||||
|
||||
|
@ -4113,6 +4155,13 @@ nsPluginInstanceOwner::Renderer::NativeDraw(Display* dpy, Drawable drawable,
|
|||
doupdatewindow = PR_TRUE;
|
||||
}
|
||||
|
||||
if (nsIntSize(mWindow->width, mWindow->height) != mPluginSize) {
|
||||
mWindow->width = mPluginSize.width;
|
||||
mWindow->height = mPluginSize.height;
|
||||
doupdatewindow = PR_TRUE;
|
||||
}
|
||||
|
||||
// The clip rect is relative to plugin top-left.
|
||||
NS_ASSERTION(numClipRects <= 1, "We don't support multiple clip rectangles!");
|
||||
nsPluginRect newClipRect;
|
||||
if (numClipRects) {
|
||||
|
@ -4420,7 +4469,7 @@ void nsPluginInstanceOwner::SetPluginHost(nsIPluginHost* aHost)
|
|||
mPluginHost = aHost;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN) || (defined(DO_DIRTY_INTERSECT) && defined(XP_MACOSX)) || defined(MOZ_X11) || defined(XP_OS2)
|
||||
#if defined(XP_WIN) || (defined(DO_DIRTY_INTERSECT) && defined(XP_MACOSX)) || defined(XP_OS2)
|
||||
// convert frame coordinates from twips to pixels
|
||||
static void ConvertAppUnitsToPixels(const nsPresContext& aPresContext, const nsRect& aTwipsRect, nsIntRect& aPixelRect)
|
||||
{
|
||||
|
|
|
@ -81,11 +81,6 @@ public:
|
|||
const nsRect& aDirtyRect,
|
||||
const nsDisplayListSet& aLists);
|
||||
|
||||
void PrintPlugin(nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect);
|
||||
void PaintPlugin(nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect);
|
||||
|
||||
NS_IMETHOD HandleEvent(nsPresContext* aPresContext,
|
||||
nsGUIEvent* aEvent,
|
||||
nsEventStatus* aEventStatus);
|
||||
|
@ -182,6 +177,17 @@ protected:
|
|||
|
||||
nsPoint GetWindowOriginInPixels(PRBool aWindowless);
|
||||
|
||||
static void PaintPrintPlugin(nsIFrame* aFrame,
|
||||
nsIRenderingContext* aRenderingContext,
|
||||
const nsRect& aDirtyRect, nsPoint aPt);
|
||||
static void PaintPlugin(nsIFrame* aFrame,
|
||||
nsIRenderingContext* aRenderingContext,
|
||||
const nsRect& aDirtyRect, nsPoint aPt);
|
||||
void PrintPlugin(nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect);
|
||||
void PaintPlugin(nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect, const nsPoint& aFramePt);
|
||||
|
||||
/**
|
||||
* Makes sure that mInstanceOwner is valid and without a current plugin
|
||||
* instance. Essentially, this prepares the frame to receive a new plugin.
|
||||
|
|
Загрузка…
Ссылка в новой задаче