fix for bug 73161 r=bryner,syd sr=waterson

This commit is contained in:
pavlov%netscape.com 2001-03-30 07:05:28 +00:00
Родитель 0ac5f40e02
Коммит 9fcf1bbca7
5 изменённых файлов: 415 добавлений и 5 удалений

Просмотреть файл

@ -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)

201
gfx/src/gtk/XIE.c Normal file
Просмотреть файл

@ -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

51
gfx/src/gtk/drawers.h Normal file
Просмотреть файл

@ -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];