зеркало из https://github.com/mozilla/gecko-dev.git
fix for bug 73161 r=bryner,syd sr=waterson
This commit is contained in:
Родитель
0ac5f40e02
Коммит
9fcf1bbca7
|
@ -33,6 +33,12 @@ REQUIRES = xpcom string img widget view util dom pref js uconv appshell necko un
|
|||
|
||||
CSRCS = nsPrintdGTK.c
|
||||
|
||||
ifndef HAVE_GDK_PIXBUF
|
||||
ifdef HAVE_XIE
|
||||
CSRCS += XIE.c
|
||||
endif
|
||||
endif
|
||||
|
||||
CPPSRCS = \
|
||||
nsDeviceContextGTK.cpp \
|
||||
nsDeviceContextSpecFactoryG.cpp \
|
||||
|
@ -66,9 +72,23 @@ ifdef MOZ_ENABLE_XINERAMA
|
|||
GFX_XINERAMA_LIBS += $(MOZ_XINERAMA_LIBS)
|
||||
endif
|
||||
|
||||
ifdef HAVE_GDK_PIXBUF
|
||||
DEFINES += -DHAVE_GDK_PIXBUF
|
||||
GFX_PIXBUF_LIBS += $(MOZ_GDK_PIXBUF_LIBS)
|
||||
CXXFLAGS += $(MOZ_GDK_PIXBUF_CFLAGS)
|
||||
CFLAGS += $(MOZ_GDK_PIXBUF_CFLAGS)
|
||||
else
|
||||
ifdef HAVE_XIE
|
||||
DEFINES += -DHAVE_XIE
|
||||
GFX_XIE_LIBS += $(MOZ_XIE_LIBS)
|
||||
endif
|
||||
endif
|
||||
|
||||
EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS) \
|
||||
-lgkgfx \
|
||||
$(GFX_XINERAMA_LIBS) \
|
||||
$(GFX_PIXBUF_LIBS) \
|
||||
$(GFX_XIE_LIBS) \
|
||||
-lgtksuperwin \
|
||||
$(MOZ_JS_LIBS) \
|
||||
$(NULL)
|
||||
|
|
|
@ -0,0 +1,201 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
* Syd Logan <syd@netscape.com>
|
||||
*/
|
||||
|
||||
#include "drawers.h"
|
||||
|
||||
#ifdef HAVE_XIE
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#include <X11/extensions/XIElib.h>
|
||||
|
||||
/*#define DEBUG_XIE 1*/
|
||||
|
||||
static PRBool inited = PR_FALSE;
|
||||
static XiePhotospace gPhotospace;
|
||||
static XiePhotoElement *photoElement;
|
||||
|
||||
static void
|
||||
DoFlo(Display *display,
|
||||
Drawable aDest,
|
||||
GC aGC,
|
||||
Drawable aSrc,
|
||||
PRInt32 aSrcWidth,
|
||||
PRInt32 aSrcHeight,
|
||||
PRInt32 aSX,
|
||||
PRInt32 aSY,
|
||||
PRInt32 aSWidth,
|
||||
PRInt32 aSHeight,
|
||||
PRInt32 aDX,
|
||||
PRInt32 aDY,
|
||||
PRInt32 aDWidth,
|
||||
PRInt32 aDHeight)
|
||||
{
|
||||
XieExtensionInfo *info;
|
||||
float coeffs[6];
|
||||
XieConstant constant;
|
||||
XiePhototag idx = 0, src;
|
||||
/* static PRBool firsttime = PR_TRUE;
|
||||
static XiePhotomap pmap;
|
||||
*/
|
||||
|
||||
/* create the pretty flo graph */
|
||||
|
||||
|
||||
|
||||
/* import */
|
||||
XieFloImportDrawable(&photoElement[idx], aSrc, aSX, aSY, aSWidth, aSHeight, 0, PR_FALSE);
|
||||
++idx;
|
||||
src = idx;
|
||||
|
||||
/* do the scaling stuff */
|
||||
coeffs[0] = (float)aSrcWidth / (float)aDWidth;
|
||||
coeffs[1] = 0.0;
|
||||
coeffs[2] = 0.0;
|
||||
coeffs[3] = (float)aSrcHeight / (float)aDHeight;
|
||||
coeffs[4] = 0.0;
|
||||
coeffs[5] = 0.0;
|
||||
|
||||
constant[0] = 128.0;
|
||||
constant[1] = 128.0;
|
||||
constant[2] = 128.0;
|
||||
|
||||
XieFloGeometry(&photoElement[idx], src, aDWidth, aDHeight,
|
||||
coeffs,
|
||||
constant,
|
||||
0x07,
|
||||
xieValGeomNearestNeighbor,
|
||||
NULL);
|
||||
++idx;
|
||||
|
||||
/* export */
|
||||
XieFloExportDrawable(&photoElement[idx], idx, aDest, aGC,
|
||||
(aDX - aSX),
|
||||
(aDY - aSY));
|
||||
++idx;
|
||||
|
||||
|
||||
/* do the scale thing baby */
|
||||
XieExecuteImmediate(display, gPhotospace, 1, PR_FALSE, photoElement, idx);
|
||||
|
||||
|
||||
/*
|
||||
XieFreePhotofloGraph(photoElement, 3);
|
||||
*/
|
||||
|
||||
#ifdef DEBUG_XIE
|
||||
gdk_flush();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PRBool
|
||||
DrawScaledImageXIE(Display *display,
|
||||
GdkDrawable *aDest,
|
||||
GdkGC *aGC,
|
||||
GdkDrawable *aSrc,
|
||||
GdkDrawable *aSrcMask,
|
||||
PRInt32 aSrcWidth,
|
||||
PRInt32 aSrcHeight,
|
||||
PRInt32 aSX,
|
||||
PRInt32 aSY,
|
||||
PRInt32 aSWidth,
|
||||
PRInt32 aSHeight,
|
||||
PRInt32 aDX,
|
||||
PRInt32 aDY,
|
||||
PRInt32 aDWidth,
|
||||
PRInt32 aDHeight)
|
||||
{
|
||||
Drawable importDrawable = GDK_WINDOW_XWINDOW(aSrc);
|
||||
Drawable exportDrawable = GDK_WINDOW_XWINDOW(aDest);
|
||||
|
||||
GdkPixmap *alphaMask = NULL;
|
||||
|
||||
GdkGC *gc = NULL;
|
||||
|
||||
#ifdef DEBUG_XIE
|
||||
printf("DrawScaledImageXIE\n");
|
||||
#endif
|
||||
|
||||
if (!inited) {
|
||||
XieExtensionInfo *info;
|
||||
inited = PR_TRUE;
|
||||
if (!XieInitialize(display, &info))
|
||||
return PR_FALSE;
|
||||
|
||||
/* create the photospace (we only need to do this once) */
|
||||
gPhotospace = XieCreatePhotospace(display);
|
||||
|
||||
photoElement = XieAllocatePhotofloGraph(3);
|
||||
|
||||
/* we want to destroy this at shutdown
|
||||
XieDestroyPhotospace(display, photospace);
|
||||
*/
|
||||
}
|
||||
|
||||
if (aSrcMask) {
|
||||
Drawable destMask;
|
||||
|
||||
#ifdef DEBUG_XIE
|
||||
fprintf(stderr, "DrawScaledImageXIE with alpha mask\n");
|
||||
#endif
|
||||
|
||||
alphaMask = gdk_pixmap_new(aSrcMask, aDWidth, aDHeight, 1);
|
||||
destMask = GDK_WINDOW_XWINDOW(alphaMask);
|
||||
gc = gdk_gc_new(alphaMask);
|
||||
DoFlo(display, destMask, GDK_GC_XGC(gc), GDK_WINDOW_XWINDOW(aSrcMask), aSrcWidth, aSrcHeight,
|
||||
aSX, aSY, aSWidth, aSHeight,
|
||||
aDX, aDY, aDWidth, aDHeight);
|
||||
gdk_gc_unref(gc);
|
||||
|
||||
gc = gdk_gc_new(aDest);
|
||||
|
||||
gdk_gc_copy(gc, aGC);
|
||||
gdk_gc_set_clip_mask(gc, alphaMask);
|
||||
gdk_gc_set_clip_origin(gc, aDX + aSX, aDY + aSY);
|
||||
}
|
||||
|
||||
if (!gc) {
|
||||
gc = aGC;
|
||||
gdk_gc_ref(gc);
|
||||
}
|
||||
|
||||
DoFlo(display, exportDrawable, GDK_GC_XGC(gc), importDrawable, aSrcWidth, aSrcHeight,
|
||||
aSX, aSY, aSWidth, aSHeight,
|
||||
aDX, aDY, aDWidth, aDHeight);
|
||||
|
||||
if (alphaMask)
|
||||
gdk_pixmap_unref(alphaMask);
|
||||
|
||||
gdk_gc_unref(gc);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,51 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "prtypes.h"
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
#ifdef HAVE_XIE
|
||||
PRBool
|
||||
DrawScaledImageXIE(Display *display,
|
||||
GdkDrawable *aDest,
|
||||
GdkGC *aGC,
|
||||
GdkDrawable *aSrc,
|
||||
GdkDrawable *aSrcMask,
|
||||
PRInt32 aSrcWidth,
|
||||
PRInt32 aSrcHeight,
|
||||
PRInt32 aSX,
|
||||
PRInt32 aSY,
|
||||
PRInt32 aSWidth,
|
||||
PRInt32 aSHeight,
|
||||
PRInt32 aDX,
|
||||
PRInt32 aDY,
|
||||
PRInt32 aDWidth,
|
||||
PRInt32 aDHeight);
|
||||
#endif
|
||||
|
||||
PR_END_EXTERN_C
|
|
@ -24,6 +24,12 @@
|
|||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#ifdef HAVE_GDK_PIXBUF
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#else
|
||||
#include "drawers.h"
|
||||
#endif
|
||||
|
||||
#include "nsImageGTK.h"
|
||||
#include "nsRenderingContextGTK.h"
|
||||
|
||||
|
@ -341,6 +347,128 @@ void nsImageGTK::ImageUpdated(nsIDeviceContext *aContext,
|
|||
static PRTime gConvertTime, gAlphaTime, gCopyStart, gCopyEnd, gStartTime, gPixmapTime, gEndTime;
|
||||
#endif
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImageGTK::DrawScaled(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
|
||||
PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
|
||||
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight)
|
||||
{
|
||||
if (aSX < mDecodedX1) {
|
||||
aSWidth -= mDecodedX1 - aSX;
|
||||
aDX += mDecodedX1 - aSX;
|
||||
aSX += mDecodedX1 - aSX;
|
||||
}
|
||||
if (aSX + aSWidth > mDecodedX2) {
|
||||
aSWidth -= aSX + aSWidth - mDecodedX2;
|
||||
}
|
||||
if (aSY < mDecodedY1) {
|
||||
aSHeight -= mDecodedY1 - aSY;
|
||||
aDY += mDecodedY1 - aSY;
|
||||
aSY += mDecodedY1 - aSY;
|
||||
}
|
||||
if (aSY + aSHeight > mDecodedY2) {
|
||||
aSHeight -= (aSY + aSHeight) - mDecodedY2;
|
||||
}
|
||||
|
||||
nsDrawingSurfaceGTK *drawing = (nsDrawingSurfaceGTK*)aSurface;
|
||||
|
||||
if (mAlphaDepth == 1) {
|
||||
CreateAlphaBitmap(mWidth, mHeight);
|
||||
}
|
||||
|
||||
#ifdef HAVE_GDK_PIXBUF
|
||||
|
||||
GdkGC *copyGC;
|
||||
if (mAlphaPixmap) {
|
||||
NS_WARNING("alpha bitmask not scaled!\n");
|
||||
if (mGC) {
|
||||
copyGC = gdk_gc_ref(mGC);
|
||||
} else {
|
||||
mGC = gdk_gc_new(drawing->GetDrawable());
|
||||
GdkGC *gc = ((nsRenderingContextGTK&)aContext).GetGC();
|
||||
gdk_gc_copy(mGC, gc);
|
||||
gdk_gc_unref(gc); // unref the one we got
|
||||
copyGC = gdk_gc_ref(mGC);
|
||||
|
||||
SetupGCForAlpha(copyGC, aDX-aSX, aDY-aSY);
|
||||
}
|
||||
} else {
|
||||
// don't make a copy... we promise not to change it
|
||||
copyGC = ((nsRenderingContextGTK&)aContext).GetGC();
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((mAlphaDepth==8) && mAlphaValid) {
|
||||
NS_WARNING("can't do 8bit alpha stretched images currently\n");
|
||||
// DrawComposited(aContext, aSurface, aSX, aSY, aDX, aDY, aSWidth, aSHeight);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#if defined(HAVE_GDK_PIXBUF)
|
||||
// Draw with GdkPixbuf
|
||||
GdkPixbuf *tmpPb =
|
||||
gdk_pixbuf_new_from_data(mImageBits,
|
||||
GDK_COLORSPACE_RGB, PR_FALSE, 8,
|
||||
mWidth, mHeight,
|
||||
mRowBytes, nsnull, nsnull);
|
||||
|
||||
GdkPixbuf *newPb = gdk_pixbuf_new(GDK_COLORSPACE_RGB, PR_FALSE,
|
||||
8,
|
||||
aDWidth, aDHeight);
|
||||
|
||||
gdk_pixbuf_scale(tmpPb, newPb, 0, 0, aDWidth, aDHeight,
|
||||
0, 0,
|
||||
(double)aDWidth / (double)aSWidth,
|
||||
(double)aDWidth / (double)aSHeight,
|
||||
GDK_INTERP_NEAREST);
|
||||
|
||||
gdk_pixbuf_render_to_drawable(newPb,
|
||||
drawing->GetDrawable(),
|
||||
copyGC,
|
||||
aSX, aSY,
|
||||
aDX + aSX, aDY + aSY,
|
||||
aDWidth, aDHeight,
|
||||
GDK_RGB_DITHER_MAX, 0, 0);
|
||||
|
||||
gdk_gc_unref(copyGC);
|
||||
gdk_pixbuf_unref(tmpPb);
|
||||
gdk_pixbuf_unref(newPb);
|
||||
|
||||
#elif defined(HAVE_XIE)
|
||||
|
||||
// Draw with XIE
|
||||
|
||||
// don't make a copy... we promise not to change it
|
||||
GdkGC *gc = ((nsRenderingContextGTK&)aContext).GetGC();
|
||||
|
||||
// DrawScaledImageXIE will copy the GC if it needs to change it.
|
||||
|
||||
PRBool succeeded = DrawScaledImageXIE(GDK_DISPLAY(),
|
||||
drawing->GetDrawable(),
|
||||
gc,
|
||||
mImagePixmap,
|
||||
mAlphaPixmap,
|
||||
mWidth, mHeight,
|
||||
aSX, aSY,
|
||||
aSWidth, aSHeight,
|
||||
aDX, aDY,
|
||||
aDWidth, aDHeight);
|
||||
|
||||
gdk_gc_unref(gc);
|
||||
|
||||
if (!succeeded) {
|
||||
NS_WARNING("unable to draw scaled image :(");
|
||||
}
|
||||
#else
|
||||
printf("no way to scale images :(\n");
|
||||
#endif
|
||||
|
||||
mFlags = 0;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// Draw the bitmap, this method has a source and destination coordinates
|
||||
NS_IMETHODIMP
|
||||
nsImageGTK::Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
|
||||
|
@ -357,6 +485,11 @@ nsImageGTK::Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
|
|||
aDX, aDY, aDWidth, aDHeight);
|
||||
#endif
|
||||
|
||||
if (aSWidth != aDWidth || aSHeight != aDHeight) {
|
||||
return DrawScaled(aContext, aSurface, aSX, aSY, aSWidth, aSHeight,
|
||||
aDX, aDY, aDWidth, aDHeight);
|
||||
}
|
||||
|
||||
if (aSX < mDecodedX1) {
|
||||
aSWidth -= mDecodedX1 - aSX;
|
||||
aDX += mDecodedX1 - aSX;
|
||||
|
|
|
@ -126,6 +126,11 @@ private:
|
|||
void ComputePaletteSize(PRIntn nBitCount);
|
||||
|
||||
private:
|
||||
|
||||
NS_IMETHOD DrawScaled(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
|
||||
PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
|
||||
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight);
|
||||
|
||||
static unsigned scaled6[1<<6];
|
||||
static unsigned scaled5[1<<5];
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче