зеркало из https://github.com/mozilla/pjs.git
Bug 395983 - "Duplicated Flash menus using r60(+) of Flash player" (do native drawing instead) [p=kinetik@flim.org (Matthew Gregan) r=vlad sr=roc a=blocking1.9+]
This commit is contained in:
Родитель
4ef483fb52
Коммит
a192027417
|
@ -81,6 +81,7 @@ EXPORTS += gfxPlatformMac.h \
|
|||
gfxQuartzImageSurface.h \
|
||||
gfxQuartzPDFSurface.h \
|
||||
gfxAtsuiFonts.h \
|
||||
gfxQuartzNativeDrawing.h \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_ENABLE_GLITZ
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Thebes gfx.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Matthew Gregan <kinetik@flim.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef _GFXQUARTZNATIVEDRAWING_H_
|
||||
#define _GFXQUARTZNATIVEDRAWING_H_
|
||||
|
||||
#include "gfxContext.h"
|
||||
#include "gfxQuartzSurface.h"
|
||||
|
||||
class THEBES_API gfxQuartzNativeDrawing {
|
||||
public:
|
||||
|
||||
/* Create native Quartz drawing for a rectangle bounded by
|
||||
* nativeRect.
|
||||
*
|
||||
* Typical usage looks like:
|
||||
*
|
||||
* gfxQuartzNativeDrawing nativeDraw(ctx, nativeRect);
|
||||
* CGContextRef cgContext = nativeDraw.BeginNativeDrawing();
|
||||
* if (!cgContext)
|
||||
* return NS_ERROR_FAILURE;
|
||||
*
|
||||
* ... call Quartz operations on CGContextRef to draw to nativeRect ...
|
||||
*
|
||||
* nativeDraw.EndNativeDrawing();
|
||||
*/
|
||||
gfxQuartzNativeDrawing(gfxContext *ctx,
|
||||
const gfxRect& nativeRect);
|
||||
|
||||
/* Returns a CGContextRef which may be used for native drawing. This
|
||||
* CGContextRef is valid until EndNativeDrawing is called; if it is used
|
||||
* for drawing after that time, the result is undefined. */
|
||||
CGContextRef BeginNativeDrawing();
|
||||
|
||||
/* Marks the end of native drawing */
|
||||
void EndNativeDrawing();
|
||||
|
||||
private:
|
||||
// don't allow copying via construction or assignment
|
||||
gfxQuartzNativeDrawing(const gfxQuartzNativeDrawing&);
|
||||
const gfxQuartzNativeDrawing& operator=(const gfxQuartzNativeDrawing&);
|
||||
|
||||
nsRefPtr<gfxContext> mContext;
|
||||
gfxRect mNativeRect; // not yet used, will be needed for offscreen buffers
|
||||
|
||||
// saved state
|
||||
nsRefPtr<gfxQuartzSurface> mQuartzSurface;
|
||||
CGContextRef mCGContext;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -109,6 +109,7 @@ CPPSRCS += \
|
|||
$(NULL)
|
||||
#CPPSRCS += gfxPDFSurface.cpp
|
||||
CPPSRCS += nsUnicodeRange.cpp
|
||||
CPPSRCS += gfxQuartzNativeDrawing.cpp
|
||||
|
||||
CMMSRCS = gfxQuartzFontCache.mm
|
||||
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Thebes gfx.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Matthew Gregan <kinetik@flim.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsMathUtils.h"
|
||||
|
||||
#include "gfxQuartzNativeDrawing.h"
|
||||
#include "gfxQuartzSurface.h"
|
||||
|
||||
// see cairo-quartz-surface.c for the complete list of these
|
||||
enum {
|
||||
kPrivateCGCompositeSourceOver = 2
|
||||
};
|
||||
|
||||
// private Quartz routine needed here
|
||||
extern "C" {
|
||||
CG_EXTERN void CGContextSetCompositeOperation(CGContextRef, int);
|
||||
}
|
||||
|
||||
gfxQuartzNativeDrawing::gfxQuartzNativeDrawing(gfxContext* ctx,
|
||||
const gfxRect& nativeRect)
|
||||
: mContext(ctx), mNativeRect(nativeRect)
|
||||
{
|
||||
}
|
||||
|
||||
CGContextRef
|
||||
gfxQuartzNativeDrawing::BeginNativeDrawing()
|
||||
{
|
||||
NS_ASSERTION(!mQuartzSurface, "BeginNativeDrawing called when drawing already in progress");
|
||||
|
||||
gfxPoint deviceOffset;
|
||||
nsRefPtr<gfxASurface> surf = mContext->CurrentSurface(&deviceOffset.x, &deviceOffset.y);
|
||||
if (!surf || surf->CairoStatus())
|
||||
return nsnull;
|
||||
|
||||
// if this is a native Quartz surface, we don't have to redirect
|
||||
// rendering to our own CGContextRef; in most cases, we are able to
|
||||
// use the CGContextRef from the surface directly. we can extend
|
||||
// this to support offscreen drawing fairly easily in the future.
|
||||
if (surf->GetType() == gfxASurface::SurfaceTypeQuartz &&
|
||||
(surf->GetContentType() == gfxASurface::CONTENT_COLOR ||
|
||||
(surf->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA))) {
|
||||
mQuartzSurface = static_cast<gfxQuartzSurface*>(static_cast<gfxASurface*>(surf.get()));
|
||||
} else {
|
||||
// XXXkinetik we could create and use a temp surface here and draw
|
||||
// it back to the gfxContext in EndNativeDrawing like the Windows
|
||||
// version of this class
|
||||
NS_WARNING("unhandled surface type");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Need to force the clip to be set
|
||||
mContext->UpdateSurfaceClip();
|
||||
|
||||
// grab the CGContextRef
|
||||
mCGContext = mQuartzSurface->GetCGContext();
|
||||
if (!mCGContext)
|
||||
return nsnull;
|
||||
|
||||
gfxMatrix m = mContext->CurrentMatrix();
|
||||
CGContextSaveGState(mCGContext);
|
||||
CGContextTranslateCTM(mCGContext, deviceOffset.x, deviceOffset.y);
|
||||
|
||||
// I -think- that this context will always have an identity
|
||||
// transform (since we don't maintain a transform on it in
|
||||
// cairo-land, and instead push/pop as needed)
|
||||
|
||||
gfxFloat x0 = m.x0;
|
||||
gfxFloat y0 = m.y0;
|
||||
|
||||
// We round x0/y0 if we don't have a scale, because otherwise things get
|
||||
// rendered badly
|
||||
// XXX how should we be rounding x0/y0?
|
||||
if (!m.HasNonTranslationOrFlip()) {
|
||||
x0 = floor(x0 + 0.5);
|
||||
y0 = floor(y0 + 0.5);
|
||||
}
|
||||
|
||||
CGContextConcatCTM(mCGContext, CGAffineTransformMake(m.xx, m.yx,
|
||||
m.xy, m.yy,
|
||||
x0, y0));
|
||||
|
||||
// bug 382049 - need to explicity set the composite operation to sourceOver
|
||||
CGContextSetCompositeOperation(mCGContext, kPrivateCGCompositeSourceOver);
|
||||
|
||||
return mCGContext;
|
||||
}
|
||||
|
||||
void
|
||||
gfxQuartzNativeDrawing::EndNativeDrawing()
|
||||
{
|
||||
NS_ASSERTION(mQuartzSurface, "EndNativeDrawing called without BeginNativeDrawing");
|
||||
|
||||
// we drew directly to a shared CGContextRef; restore previous context state
|
||||
CGContextRestoreGState(mCGContext);
|
||||
mQuartzSurface->MarkDirty();
|
||||
mQuartzSurface = nsnull;
|
||||
}
|
|
@ -145,6 +145,10 @@
|
|||
#include "nsContentCID.h"
|
||||
static NS_DEFINE_CID(kRangeCID, NS_RANGE_CID);
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include "gfxQuartzNativeDrawing.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_X11
|
||||
#include <X11/Xlib.h>
|
||||
/* X headers suck */
|
||||
|
@ -1250,8 +1254,35 @@ nsObjectFrame::PaintPlugin(nsIRenderingContext& aRenderingContext,
|
|||
// Screen painting code
|
||||
#if defined(XP_MACOSX)
|
||||
// delegate all painting to the plugin instance.
|
||||
if (mInstanceOwner)
|
||||
if (mInstanceOwner) {
|
||||
if (mInstanceOwner->GetDrawingModel() == NPDrawingModelCoreGraphics) {
|
||||
PRInt32 p2a = PresContext()->AppUnitsPerDevPixel();
|
||||
gfxRect nativeClipRect(aDirtyRect.x, aDirtyRect.y,
|
||||
aDirtyRect.width, aDirtyRect.height);
|
||||
nativeClipRect.ScaleInverse(gfxFloat(p2a));
|
||||
gfxContext* ctx = aRenderingContext.ThebesContext();
|
||||
gfxQuartzNativeDrawing nativeDrawing(ctx, nativeClipRect);
|
||||
|
||||
CGContextRef cgContext = nativeDrawing.BeginNativeDrawing();
|
||||
if (!cgContext) {
|
||||
NS_WARNING("null CGContextRef during PaintPlugin");
|
||||
return;
|
||||
}
|
||||
|
||||
// XXXkinetik if gfxQuartzNativeDrawing ever gave us a CGContext other
|
||||
// than the current one, we would need to pass that to the plugin via
|
||||
// SetWindow, just assert that they're the same for now
|
||||
nsPluginPort* pluginPort = mInstanceOwner->GetPluginPort();
|
||||
NS_ASSERTION(pluginPort->cgPort.context == cgContext,
|
||||
"BeginNativeDrawing using different CGContextRef to plugin");
|
||||
|
||||
mInstanceOwner->Paint(aDirtyRect);
|
||||
|
||||
nativeDrawing.EndNativeDrawing();
|
||||
} else {
|
||||
mInstanceOwner->Paint(aDirtyRect);
|
||||
}
|
||||
}
|
||||
#elif defined(MOZ_X11)
|
||||
if (mInstanceOwner)
|
||||
{
|
||||
|
|
|
@ -649,10 +649,7 @@ void* nsChildView::GetNativeData(PRUint32 aDataType)
|
|||
if ([mView isKindOfClass:[ChildView class]])
|
||||
[(ChildView*)mView setIsPluginView:YES];
|
||||
|
||||
if ([NSView focusView] == mView)
|
||||
mPluginPort.cgPort.context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
|
||||
else
|
||||
mPluginPort.cgPort.context = NULL;
|
||||
mPluginPort.cgPort.context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
|
||||
|
||||
NSWindow* window = [mView nativeWindow];
|
||||
if (window) {
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
* Vladimir Vukicevic <vladimir@pobox.com> (HITheme rewrite)
|
||||
* Josh Aas <josh@mozilla.com>
|
||||
* Colin Barrett <cbarrett@mozilla.com>
|
||||
* Matthew Gregan <kinetik@flim.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
|
@ -58,19 +59,14 @@
|
|||
|
||||
#include "gfxContext.h"
|
||||
#include "gfxQuartzSurface.h"
|
||||
#include "gfxQuartzNativeDrawing.h"
|
||||
|
||||
#define DRAW_IN_FRAME_DEBUG 0
|
||||
#define SCROLLBARS_VISUAL_DEBUG 0
|
||||
|
||||
// see cairo-quartz-surface.c for the complete list of these
|
||||
enum {
|
||||
kPrivateCGCompositeSourceOver = 2
|
||||
};
|
||||
|
||||
// private Quartz routines needed here
|
||||
extern "C" {
|
||||
CG_EXTERN void CGContextSetCTM(CGContextRef, CGAffineTransform);
|
||||
CG_EXTERN void CGContextSetCompositeOperation (CGContextRef, int);
|
||||
}
|
||||
|
||||
// Copied from nsLookAndFeel.h
|
||||
|
@ -844,30 +840,18 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsIRenderingContext* aContext, nsIFrame
|
|||
aContext->GetDeviceContext(*getter_AddRefs(dctx));
|
||||
PRInt32 p2a = dctx->AppUnitsPerDevPixel();
|
||||
|
||||
gfxRect nativeClipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height);
|
||||
gfxRect nativeWidgetRect(aRect.x, aRect.y, aRect.width, aRect.height);
|
||||
nativeWidgetRect.ScaleInverse(gfxFloat(p2a));
|
||||
nativeClipRect.ScaleInverse(gfxFloat(p2a));
|
||||
|
||||
nsRefPtr<gfxContext> thebesCtx = aContext->ThebesContext();
|
||||
if (!thebesCtx)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
thebesCtx->UpdateSurfaceClip();
|
||||
|
||||
double offsetX = 0.0, offsetY = 0.0;
|
||||
nsRefPtr<gfxASurface> thebesSurface = thebesCtx->CurrentSurface(&offsetX, &offsetY);
|
||||
if (thebesSurface->CairoStatus() != 0) {
|
||||
NS_WARNING("Got Cairo surface with nonzero error status");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (thebesSurface->GetType() != gfxASurface::SurfaceTypeQuartz) {
|
||||
NS_WARNING("Expected surface of type Quartz, got something else");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
gfxMatrix mat = thebesCtx->CurrentMatrix();
|
||||
gfxQuartzSurface* quartzSurf = (gfxQuartzSurface*) (thebesSurface.get());
|
||||
CGContextRef cgContext = quartzSurf->GetCGContext();
|
||||
|
||||
//fprintf (stderr, "surface: %p cgContext: %p\n", quartzSurf, cgContext);
|
||||
gfxQuartzNativeDrawing nativeDrawing(thebesCtx, nativeClipRect);
|
||||
|
||||
CGContextRef cgContext = nativeDrawing.BeginNativeDrawing();
|
||||
if (cgContext == nsnull) {
|
||||
// The Quartz surface handles 0x0 surfaces by internally
|
||||
// making all operations no-ops; there's no cgcontext created for them.
|
||||
|
@ -876,37 +860,6 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsIRenderingContext* aContext, nsIFrame
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Eventually we can just do a GetCTM and restore it with SetCTM,
|
||||
// but for now do a full save/restore
|
||||
CGAffineTransform mm0 = CGContextGetCTM(cgContext);
|
||||
|
||||
CGContextSaveGState(cgContext);
|
||||
//CGContextSetCTM(cgContext, CGAffineTransformIdentity);
|
||||
|
||||
// Apply any origin offset we have first, so it gets picked up by any other
|
||||
// transforms we have.
|
||||
CGContextTranslateCTM(cgContext, offsetX, offsetY);
|
||||
|
||||
// I -think- that this context will always have an identity
|
||||
// transform (since we don't maintain a transform on it in
|
||||
// cairo-land, and instead push/pop as needed)
|
||||
if (mat.HasNonTranslationOrFlip()) {
|
||||
// If we have a scale, I think we've already lost; so don't round
|
||||
// anything here
|
||||
CGContextConcatCTM(cgContext,
|
||||
CGAffineTransformMake(mat.xx, mat.yx,
|
||||
mat.xy, mat.yy,
|
||||
mat.x0, mat.y0));
|
||||
} else {
|
||||
// Otherwise, we round the x0/y0, because otherwise things get rendered badly
|
||||
// XXX how should we be rounding the x0/y0?
|
||||
CGContextConcatCTM(cgContext,
|
||||
CGAffineTransformMake(mat.xx, mat.yx,
|
||||
mat.xy, mat.yy,
|
||||
floor(mat.x0 + 0.5),
|
||||
floor(mat.y0 + 0.5)));
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (1 /*aWidgetType == NS_THEME_TEXTFIELD*/) {
|
||||
fprintf(stderr, "Native theme drawing widget %d [%p] dis:%d in rect [%d %d %d %d]\n",
|
||||
|
@ -926,9 +879,6 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsIRenderingContext* aContext, nsIFrame
|
|||
NSAppUnitsToIntPixels(aRect.width, p2a),
|
||||
NSAppUnitsToIntPixels(aRect.height, p2a));
|
||||
|
||||
// 382049 - need to explicitly set the composite operation to sourceOver
|
||||
CGContextSetCompositeOperation(cgContext, kPrivateCGCompositeSourceOver);
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, " --> macRect %f %f %f %f\n",
|
||||
macRect.origin.x, macRect.origin.y, macRect.size.width, macRect.size.height);
|
||||
|
@ -1230,7 +1180,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsIRenderingContext* aContext, nsIFrame
|
|||
break;
|
||||
}
|
||||
|
||||
CGContextRestoreGState(cgContext);
|
||||
nativeDrawing.EndNativeDrawing();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче