mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-05 16:22:53 +00:00
Bug 83920 - remove XIE and gdkpixbuf options for image scaling.
New hand scaler - should be faster and can do 8-bit transparency scaling. r=pavlov, sr=blizzard, a=asa
This commit is contained in:
parent
0b6882ecc1
commit
bd98991c58
@ -34,12 +34,6 @@ REQUIRES = xpcom string img widget view util dom pref js uconv necko unicharutil
|
||||
|
||||
CSRCS = nsPrintdGTK.c
|
||||
|
||||
ifdef HAVE_XIE
|
||||
CSRCS += XIE.c
|
||||
endif
|
||||
|
||||
CSRCS += scale.c
|
||||
|
||||
CPPSRCS = \
|
||||
nsDeviceContextGTK.cpp \
|
||||
nsDeviceContextSpecFactoryG.cpp \
|
||||
@ -55,6 +49,7 @@ CPPSRCS = \
|
||||
nsScreenGtk.cpp \
|
||||
nsScreenManagerGtk.cpp \
|
||||
nsPrintOptionsGTK.cpp \
|
||||
scale.cpp \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
@ -73,22 +68,9 @@ 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)
|
||||
endif
|
||||
ifdef HAVE_XIE
|
||||
DEFINES += -DHAVE_XIE
|
||||
GFX_XIE_LIBS += $(MOZ_XIE_LIBS)
|
||||
endif
|
||||
|
||||
EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS) \
|
||||
-lgkgfx \
|
||||
$(GFX_XINERAMA_LIBS) \
|
||||
$(GFX_PIXBUF_LIBS) \
|
||||
$(GFX_XIE_LIBS) \
|
||||
-lgtksuperwin \
|
||||
$(MOZ_JS_LIBS) \
|
||||
$(NULL)
|
||||
|
@ -1,228 +0,0 @@
|
||||
/* -*- 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>
|
||||
|
||||
#include "prenv.h"
|
||||
|
||||
/*#define DEBUG_XIE 1*/
|
||||
|
||||
static PRBool useXIE = PR_TRUE;
|
||||
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;
|
||||
|
||||
/* 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 (!useXIE) {
|
||||
#ifdef DEBUG_XIE
|
||||
fprintf(stderr, "useXIE is false.\n");
|
||||
#endif
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (!inited) {
|
||||
XieExtensionInfo *info;
|
||||
|
||||
if (useXIE) {
|
||||
char *text = PR_GetEnv("MOZ_DISABLE_XIE");
|
||||
if (text) {
|
||||
#ifdef DEBUG_XIE
|
||||
fprintf(stderr, "MOZ_DISABLE_XIE set, disabling use of XIE.\n");
|
||||
#endif
|
||||
useXIE = PR_FALSE;
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!XieInitialize(display, &info)) {
|
||||
useXIE = PR_FALSE;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
inited = PR_TRUE;
|
||||
|
||||
/* create the photospace (we only need to do this once) */
|
||||
gPhotospace = XieCreatePhotospace(display);
|
||||
|
||||
photoElement = XieAllocatePhotofloGraph(3);
|
||||
|
||||
/* XXX 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);
|
||||
/* run the flo on the alpha mask to get a scaled alpha mask */
|
||||
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);
|
||||
}
|
||||
|
||||
/* run the flo on the image to get a the scaled image */
|
||||
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
|
@ -1,86 +0,0 @@
|
||||
/* -*- 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
|
||||
|
||||
PRBool
|
||||
DrawScaledImageNN(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);
|
||||
|
||||
PRBool
|
||||
DrawScaledImageBitsNN(Display *display,
|
||||
GdkDrawable *aDest,
|
||||
GdkGC *aGC,
|
||||
const PRUint8 *aSrc,
|
||||
PRInt32 aBytesPerRow,
|
||||
const PRUint8 *aSrcMask,
|
||||
PRInt32 aSrcWidth,
|
||||
PRInt32 aSrcHeight,
|
||||
PRInt32 aSX,
|
||||
PRInt32 aSY,
|
||||
PRInt32 aSWidth,
|
||||
PRInt32 aSHeight,
|
||||
PRInt32 aDX,
|
||||
PRInt32 aDY,
|
||||
PRInt32 aDWidth,
|
||||
PRInt32 aDHeight);
|
||||
|
||||
PR_END_EXTERN_C
|
@ -20,16 +20,11 @@
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
* Tim Rowley <tor@cs.brown.edu> -- 8bit alpha compositing
|
||||
* Syd Logan <syd@netscape.com> -- simple Nearest Neighbor scaling
|
||||
*/
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#ifdef HAVE_GDK_PIXBUF
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#endif
|
||||
|
||||
#include "drawers.h"
|
||||
#include "scale.h"
|
||||
|
||||
#include "nsImageGTK.h"
|
||||
#include "nsRenderingContextGTK.h"
|
||||
@ -450,120 +445,91 @@ nsImageGTK::DrawScaled(nsIRenderingContext &aContext,
|
||||
}
|
||||
|
||||
if ((mAlphaDepth==8) && mAlphaValid) {
|
||||
NS_WARNING("can't do 8bit alpha stretched images currently\n");
|
||||
// DrawComposited(aContext, aSurface, aSX, aSY, aDX, aDY, aSWidth, aSHeight);
|
||||
DrawComposited(aContext, aSurface,
|
||||
aSX, aSY, aSWidth, aSHeight,
|
||||
aDX, aDY, aDWidth, aDHeight);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool succeeded = PR_FALSE;
|
||||
GdkGC *gc;
|
||||
GdkPixmap *pixmap = 0;
|
||||
|
||||
#ifdef HAVE_XIE
|
||||
// Draw with XIE
|
||||
if (mAlphaDepth==1) {
|
||||
PRUint32 scaledRowBytes = (aDWidth+7)>>3; // round to next byte
|
||||
PRUint8 *scaledAlpha = (PRUint8 *)nsMemory::Alloc(aDHeight*scaledRowBytes);
|
||||
|
||||
// don't make a copy... we promise not to change it
|
||||
GdkGC *gc = ((nsRenderingContextGTK&)aContext).GetGC();
|
||||
// code below attempts to draw the image without the mask if mask
|
||||
// creation fails for some reason. thus no easy-out "return"
|
||||
if (scaledAlpha) {
|
||||
memset(scaledAlpha, 0, aDHeight*scaledRowBytes);
|
||||
RectStretch(aSX, aSY, aSX+aSWidth-1, aSY+aSHeight-1,
|
||||
0, 0, aDWidth-1, aDHeight-1,
|
||||
mAlphaBits, mAlphaRowBytes, scaledAlpha, scaledRowBytes, 1);
|
||||
|
||||
pixmap = gdk_pixmap_new(nsnull, aDWidth, aDHeight, 1);
|
||||
XImage *ximage = 0;
|
||||
|
||||
// DrawScaledImageXIE will copy the GC if it needs to change it.
|
||||
if (pixmap) {
|
||||
ximage = XCreateImage(GDK_WINDOW_XDISPLAY(pixmap),
|
||||
GDK_VISUAL_XVISUAL(gdk_rgb_get_visual()),
|
||||
1, XYPixmap, 0, (char *)scaledAlpha,
|
||||
aDWidth, aDHeight,
|
||||
8, scaledRowBytes);
|
||||
}
|
||||
if (ximage) {
|
||||
ximage->bits_per_pixel=1;
|
||||
ximage->bitmap_bit_order=MSBFirst;
|
||||
ximage->byte_order = MSBFirst;
|
||||
|
||||
GdkGC *tmpGC = gdk_gc_new(pixmap);
|
||||
if (tmpGC) {
|
||||
XPutImage(GDK_WINDOW_XDISPLAY(pixmap), GDK_WINDOW_XWINDOW(pixmap),
|
||||
GDK_GC_XGC(tmpGC), ximage,
|
||||
0, 0, 0, 0, aDWidth, aDHeight);
|
||||
gdk_gc_unref(tmpGC);
|
||||
} else {
|
||||
// can't write into the clip mask - destroy so we don't use it
|
||||
if (pixmap)
|
||||
gdk_pixmap_unref(pixmap);
|
||||
pixmap = 0;
|
||||
}
|
||||
|
||||
ximage->data = 0;
|
||||
XDestroyImage(ximage);
|
||||
}
|
||||
|
||||
succeeded = DrawScaledImageXIE(GDK_DISPLAY(),
|
||||
drawing->GetDrawable(),
|
||||
gc,
|
||||
mImagePixmap,
|
||||
mAlphaPixmap,
|
||||
mWidth, mHeight,
|
||||
aSX, aSY,
|
||||
aSWidth, aSHeight,
|
||||
aDX, aDY,
|
||||
aDWidth, aDHeight);
|
||||
|
||||
gdk_gc_unref(gc);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GDK_PIXBUF
|
||||
if (!succeeded) {
|
||||
GdkGC *copyGC;
|
||||
if (mAlphaPixmap) {
|
||||
NS_WARNING("alpha bitmask not scaled!\n");
|
||||
copyGC = gdk_gc_new(drawing->GetDrawable());
|
||||
GdkGC *gc = ((nsRenderingContextGTK&)aContext).GetGC();
|
||||
gdk_gc_copy(copyGC, gc);
|
||||
gdk_gc_unref(gc); // unref the one we got
|
||||
|
||||
SetupGCForAlpha(copyGC, aDX-aSX, aDY-aSY);
|
||||
} else {
|
||||
// don't make a copy... we promise not to change it
|
||||
copyGC = ((nsRenderingContextGTK&)aContext).GetGC();
|
||||
nsMemory::Free(scaledAlpha);
|
||||
}
|
||||
|
||||
// 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)aDHeight / (double)aSHeight,
|
||||
GDK_INTERP_NEAREST);
|
||||
|
||||
gdk_pixbuf_render_to_drawable(newPb,
|
||||
drawing->GetDrawable(),
|
||||
copyGC,
|
||||
0, 0,
|
||||
aDX, aDY,
|
||||
aDWidth, aDHeight,
|
||||
GDK_RGB_DITHER_MAX, 0, 0);
|
||||
|
||||
succeeded = PR_TRUE;
|
||||
|
||||
gdk_gc_unref(copyGC);
|
||||
gdk_pixbuf_unref(tmpPb);
|
||||
gdk_pixbuf_unref(newPb);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!succeeded) {
|
||||
if (pixmap) {
|
||||
gc = gdk_gc_new(drawing->GetDrawable());
|
||||
gdk_gc_set_clip_origin(gc, aDX, aDY);
|
||||
gdk_gc_set_clip_mask(gc, pixmap);
|
||||
} else {
|
||||
// don't make a copy... we promise not to change it
|
||||
GdkGC *gc = ((nsRenderingContextGTK&)aContext).GetGC();
|
||||
gc = ((nsRenderingContextGTK&)aContext).GetGC();
|
||||
}
|
||||
|
||||
PRUint8 *scaledRGB = (PRUint8 *)nsMemory::Alloc(3*aDWidth*aDHeight);
|
||||
if (scaledRGB && gc) {
|
||||
RectStretch(aSX, aSY, aSX+aSWidth-1, aSY+aSHeight-1,
|
||||
0, 0, aDWidth-1, aDHeight-1,
|
||||
mImageBits, mRowBytes, scaledRGB, 3*aDWidth, 24);
|
||||
|
||||
gdk_draw_rgb_image(drawing->GetDrawable(), gc,
|
||||
aDX, aDY, aDWidth, aDHeight,
|
||||
GDK_RGB_DITHER_MAX,
|
||||
scaledRGB, 3*aDWidth);
|
||||
|
||||
|
||||
#if 1
|
||||
// this should work, but isn't very fast (espically over remote connections
|
||||
succeeded = DrawScaledImageNN(GDK_DISPLAY(),
|
||||
drawing->GetDrawable(),
|
||||
gc,
|
||||
mImagePixmap,
|
||||
mAlphaPixmap,
|
||||
mWidth, mHeight,
|
||||
aSX, aSY,
|
||||
aSWidth, aSHeight,
|
||||
aDX, aDY,
|
||||
aDWidth, aDHeight);
|
||||
#else
|
||||
// XXX this doesn't work very well.
|
||||
succeeded = DrawScaledImageBitsNN(GDK_DISPLAY(),
|
||||
drawing->GetDrawable(),
|
||||
gc,
|
||||
mImageBits,
|
||||
mRowBytes,
|
||||
mAlphaBits,
|
||||
mWidth, mHeight,
|
||||
aSX, aSY,
|
||||
aSWidth, aSHeight,
|
||||
aDX, aDY,
|
||||
aDWidth, aDHeight);
|
||||
#endif
|
||||
|
||||
gdk_gc_unref(gc);
|
||||
nsMemory::Free(scaledRGB);
|
||||
}
|
||||
|
||||
if (gc)
|
||||
gdk_gc_unref(gc);
|
||||
if (pixmap)
|
||||
gdk_pixmap_unref(pixmap);
|
||||
|
||||
mFlags = 0;
|
||||
|
||||
return NS_OK;
|
||||
@ -626,7 +592,9 @@ nsImageGTK::Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
|
||||
return NS_OK;
|
||||
|
||||
if ((mAlphaDepth==8) && mAlphaValid) {
|
||||
DrawComposited(aContext, aSurface, aSX, aSY, aDX, aDY, aSWidth, aSHeight);
|
||||
DrawComposited(aContext, aSurface,
|
||||
aSX, aSY, aSWidth, aSHeight,
|
||||
aDX, aDY, aSWidth, aSHeight);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -717,7 +685,8 @@ findIndex24(unsigned mask)
|
||||
// 32-bit (888) truecolor convert/composite function
|
||||
void
|
||||
nsImageGTK::DrawComposited32(PRBool isLSB, PRBool flipBytes,
|
||||
unsigned offsetX, unsigned offsetY,
|
||||
PRUint8 *imageOrigin, PRUint32 imageStride,
|
||||
PRUint8 *alphaOrigin, PRUint32 alphaStride,
|
||||
unsigned width, unsigned height,
|
||||
XImage *ximage, unsigned char *readData)
|
||||
{
|
||||
@ -740,8 +709,8 @@ nsImageGTK::DrawComposited32(PRBool isLSB, PRBool flipBytes,
|
||||
unsigned char *baseRow = (unsigned char *)ximage->data
|
||||
+y*ximage->bytes_per_line;
|
||||
unsigned char *targetRow = readData +3*(y*ximage->width);
|
||||
unsigned char *imageRow = mImageBits +(y+offsetY)*mRowBytes+3*offsetX;
|
||||
unsigned char *alphaRow = mAlphaBits +(y+offsetY)*mAlphaRowBytes+offsetX;
|
||||
unsigned char *imageRow = imageOrigin + y*imageStride;
|
||||
unsigned char *alphaRow = alphaOrigin + y*alphaStride;
|
||||
|
||||
for (unsigned i=0; i<width;
|
||||
i++, baseRow+=4, targetRow+=3, imageRow+=3, alphaRow++) {
|
||||
@ -756,7 +725,8 @@ nsImageGTK::DrawComposited32(PRBool isLSB, PRBool flipBytes,
|
||||
// 24-bit (888) truecolor convert/composite function
|
||||
void
|
||||
nsImageGTK::DrawComposited24(PRBool isLSB, PRBool flipBytes,
|
||||
unsigned offsetX, unsigned offsetY,
|
||||
PRUint8 *imageOrigin, PRUint32 imageStride,
|
||||
PRUint8 *alphaOrigin, PRUint32 alphaStride,
|
||||
unsigned width, unsigned height,
|
||||
XImage *ximage, unsigned char *readData)
|
||||
{
|
||||
@ -775,8 +745,8 @@ nsImageGTK::DrawComposited24(PRBool isLSB, PRBool flipBytes,
|
||||
unsigned char *baseRow = (unsigned char *)ximage->data
|
||||
+y*ximage->bytes_per_line;
|
||||
unsigned char *targetRow = readData +3*(y*ximage->width);
|
||||
unsigned char *imageRow = mImageBits +(y+offsetY)*mRowBytes+3*offsetX;
|
||||
unsigned char *alphaRow = mAlphaBits +(y+offsetY)*mAlphaRowBytes+offsetX;
|
||||
unsigned char *imageRow = imageOrigin + y*imageStride;
|
||||
unsigned char *alphaRow = alphaOrigin + y*alphaStride;
|
||||
|
||||
for (unsigned i=0; i<width;
|
||||
i++, baseRow+=3, targetRow+=3, imageRow+=3, alphaRow++) {
|
||||
@ -803,7 +773,8 @@ unsigned nsImageGTK::scaled5[1<<5] = {
|
||||
// 16-bit ([56][56][56]) truecolor convert/composite function
|
||||
void
|
||||
nsImageGTK::DrawComposited16(PRBool isLSB, PRBool flipBytes,
|
||||
unsigned offsetX, unsigned offsetY,
|
||||
PRUint8 *imageOrigin, PRUint32 imageStride,
|
||||
PRUint8 *alphaOrigin, PRUint32 alphaStride,
|
||||
unsigned width, unsigned height,
|
||||
XImage *ximage, unsigned char *readData)
|
||||
{
|
||||
@ -817,8 +788,8 @@ nsImageGTK::DrawComposited16(PRBool isLSB, PRBool flipBytes,
|
||||
unsigned char *baseRow = (unsigned char *)ximage->data
|
||||
+y*ximage->bytes_per_line;
|
||||
unsigned char *targetRow = readData +3*(y*ximage->width);
|
||||
unsigned char *imageRow = mImageBits +(y+offsetY)*mRowBytes+3*offsetX;
|
||||
unsigned char *alphaRow = mAlphaBits +(y+offsetY)*mAlphaRowBytes+offsetX;
|
||||
unsigned char *imageRow = imageOrigin + y*imageStride;
|
||||
unsigned char *alphaRow = alphaOrigin + y*alphaStride;
|
||||
|
||||
for (unsigned i=0; i<width;
|
||||
i++, baseRow+=2, targetRow+=3, imageRow+=3, alphaRow++) {
|
||||
@ -847,7 +818,8 @@ nsImageGTK::DrawComposited16(PRBool isLSB, PRBool flipBytes,
|
||||
// Generic convert/composite function
|
||||
void
|
||||
nsImageGTK::DrawCompositedGeneral(PRBool isLSB, PRBool flipBytes,
|
||||
unsigned offsetX, unsigned offsetY,
|
||||
PRUint8 *imageOrigin, PRUint32 imageStride,
|
||||
PRUint8 *alphaOrigin, PRUint32 alphaStride,
|
||||
unsigned width, unsigned height,
|
||||
XImage *ximage, unsigned char *readData)
|
||||
{
|
||||
@ -976,8 +948,8 @@ nsImageGTK::DrawCompositedGeneral(PRBool isLSB, PRBool flipBytes,
|
||||
// now composite
|
||||
for (unsigned y=0; y<height; y++) {
|
||||
unsigned char *targetRow = readData+3*y*width;
|
||||
unsigned char *imageRow = mImageBits +(y+offsetY)*mRowBytes+3*offsetX;
|
||||
unsigned char *alphaRow = mAlphaBits +(y+offsetY)*mAlphaRowBytes+offsetX;
|
||||
unsigned char *imageRow = imageOrigin + y*imageStride;
|
||||
unsigned char *alphaRow = alphaOrigin + y*alphaStride;
|
||||
|
||||
for (unsigned i=0; i<width; i++) {
|
||||
unsigned alpha = alphaRow[i];
|
||||
@ -992,10 +964,11 @@ void
|
||||
nsImageGTK::DrawComposited(nsIRenderingContext &aContext,
|
||||
nsDrawingSurface aSurface,
|
||||
PRInt32 aSX, PRInt32 aSY,
|
||||
PRInt32 aSWidth, PRInt32 aSHeight,
|
||||
PRInt32 aDX, PRInt32 aDY,
|
||||
PRInt32 aWidth, PRInt32 aHeight)
|
||||
PRInt32 aDWidth, PRInt32 aDHeight)
|
||||
{
|
||||
if ((aWidth==0) || (aHeight==0))
|
||||
if ((aDWidth==0) || (aDHeight==0))
|
||||
return;
|
||||
|
||||
nsDrawingSurfaceGTK* drawing = (nsDrawingSurfaceGTK*) aSurface;
|
||||
@ -1012,7 +985,7 @@ nsImageGTK::DrawComposited(nsIRenderingContext &aContext,
|
||||
unsigned readWidth, readHeight, destX, destY;
|
||||
|
||||
if ((aDY>=(int)surfaceHeight) || (aDX>=(int)surfaceWidth) ||
|
||||
(aDY+aHeight<=0) || (aDX+aWidth<=0)) {
|
||||
(aDY+aDHeight<=0) || (aDX+aDWidth<=0)) {
|
||||
// This should never happen if the layout engine is sane,
|
||||
// as it means we're trying to draw an image which is outside
|
||||
// the drawing surface. Bulletproof gfx for now...
|
||||
@ -1020,14 +993,14 @@ nsImageGTK::DrawComposited(nsIRenderingContext &aContext,
|
||||
}
|
||||
|
||||
if (aDX<0) {
|
||||
readX = 0; readWidth = aWidth+aDX; destX = aSX-aDX;
|
||||
readX = 0; readWidth = aDWidth+aDX; destX = aSX-aDX;
|
||||
} else {
|
||||
readX = aDX; readWidth = aWidth; destX = aSX;
|
||||
readX = aDX; readWidth = aDWidth; destX = aSX;
|
||||
}
|
||||
if (aDY<0) {
|
||||
readY = 0; readHeight = aHeight+aDY; destY = aSY-aDY;
|
||||
readY = 0; readHeight = aDHeight+aDY; destY = aSY-aDY;
|
||||
} else {
|
||||
readY = aDY; readHeight = aHeight; destY = aSY;
|
||||
readY = aDY; readHeight = aDHeight; destY = aSY;
|
||||
}
|
||||
|
||||
if (readX+readWidth > surfaceWidth)
|
||||
@ -1051,8 +1024,47 @@ nsImageGTK::DrawComposited(nsIRenderingContext &aContext,
|
||||
if (!ximage)
|
||||
return;
|
||||
|
||||
unsigned char *readData = new unsigned char[3*readWidth*readHeight];
|
||||
unsigned char *readData =
|
||||
(unsigned char *)nsMemory::Alloc(3*readWidth*readHeight);
|
||||
|
||||
PRUint8 *scaledImage = 0;
|
||||
PRUint8 *scaledAlpha = 0;
|
||||
PRUint8 *imageOrigin, *alphaOrigin;
|
||||
PRUint32 imageStride, alphaStride;
|
||||
if ((aSWidth!=aDWidth) || (aSHeight!=aDHeight)) {
|
||||
PRUint32 x1, y1, x2, y2;
|
||||
x1 = (destX*aSWidth)/aDWidth;
|
||||
y1 = (destY*aSHeight)/aDHeight;
|
||||
x2 = ((destX+readWidth)*aSWidth)/aDWidth;
|
||||
y2 = ((destY+readHeight)*aSHeight)/aDHeight;
|
||||
|
||||
scaledImage = (PRUint8 *)nsMemory::Alloc(3*aDWidth*aDHeight);
|
||||
scaledAlpha = (PRUint8 *)nsMemory::Alloc(aDWidth*aDHeight);
|
||||
if (!scaledImage || !scaledAlpha) {
|
||||
XDestroyImage(ximage);
|
||||
nsMemory::Free(readData);
|
||||
if (scaledImage)
|
||||
nsMemory::Free(scaledImage);
|
||||
if (scaledAlpha)
|
||||
nsMemory::Free(scaledAlpha);
|
||||
return;
|
||||
}
|
||||
RectStretch(x1, y1, x2-1, y2-1,
|
||||
0, 0, readWidth-1, readHeight-1,
|
||||
mImageBits, mRowBytes, scaledImage, 3*readWidth, 24);
|
||||
RectStretch(x1, y1, x2-1, y2-1,
|
||||
0, 0, readWidth-1, readHeight-1,
|
||||
mAlphaBits, mAlphaRowBytes, scaledAlpha, readWidth, 8);
|
||||
imageOrigin = scaledImage;
|
||||
imageStride = 3*readWidth;
|
||||
alphaOrigin = scaledAlpha;
|
||||
alphaStride = readWidth;
|
||||
} else {
|
||||
imageOrigin = mImageBits + destY*mRowBytes + 3*destX;
|
||||
imageStride = mRowBytes;
|
||||
alphaOrigin = mAlphaBits + destY*mAlphaRowBytes + destX;
|
||||
alphaStride = mAlphaRowBytes;
|
||||
}
|
||||
|
||||
PRBool isLSB;
|
||||
unsigned test = 1;
|
||||
@ -1066,23 +1078,31 @@ nsImageGTK::DrawComposited(nsIRenderingContext &aContext,
|
||||
(visual->red_prec == 8) &&
|
||||
(visual->green_prec == 8) &&
|
||||
(visual->blue_prec == 8))
|
||||
DrawComposited32(isLSB, flipBytes, destX, destY, readWidth, readHeight,
|
||||
ximage, readData);
|
||||
DrawComposited32(isLSB, flipBytes,
|
||||
imageOrigin, imageStride,
|
||||
alphaOrigin, alphaStride,
|
||||
readWidth, readHeight, ximage, readData);
|
||||
else if ((ximage->bits_per_pixel==24) &&
|
||||
(visual->red_prec == 8) &&
|
||||
(visual->green_prec == 8) &&
|
||||
(visual->blue_prec == 8))
|
||||
DrawComposited24(isLSB, flipBytes, destX, destY, readWidth, readHeight,
|
||||
ximage, readData);
|
||||
DrawComposited24(isLSB, flipBytes,
|
||||
imageOrigin, imageStride,
|
||||
alphaOrigin, alphaStride,
|
||||
readWidth, readHeight, ximage, readData);
|
||||
else if ((ximage->bits_per_pixel==16) &&
|
||||
((visual->red_prec == 5) || (visual->red_prec == 6)) &&
|
||||
((visual->green_prec == 5) || (visual->green_prec == 6)) &&
|
||||
((visual->blue_prec == 5) || (visual->blue_prec == 6)))
|
||||
DrawComposited16(isLSB, flipBytes, destX, destY, readWidth, readHeight,
|
||||
ximage, readData);
|
||||
DrawComposited16(isLSB, flipBytes,
|
||||
imageOrigin, imageStride,
|
||||
alphaOrigin, alphaStride,
|
||||
readWidth, readHeight, ximage, readData);
|
||||
else
|
||||
DrawCompositedGeneral(isLSB, flipBytes, destX, destY, readWidth, readHeight,
|
||||
ximage, readData);
|
||||
DrawCompositedGeneral(isLSB, flipBytes,
|
||||
imageOrigin, imageStride,
|
||||
alphaOrigin, alphaStride,
|
||||
readWidth, readHeight, ximage, readData);
|
||||
|
||||
GdkGC *imageGC = ((nsRenderingContextGTK&)aContext).GetGC();
|
||||
gdk_draw_rgb_image(drawing->GetDrawable(), imageGC,
|
||||
@ -1092,7 +1112,11 @@ nsImageGTK::DrawComposited(nsIRenderingContext &aContext,
|
||||
gdk_gc_unref(imageGC);
|
||||
|
||||
XDestroyImage(ximage);
|
||||
delete [] readData;
|
||||
nsMemory::Free(readData);
|
||||
if (scaledImage)
|
||||
nsMemory::Free(scaledImage);
|
||||
if (scaledAlpha)
|
||||
nsMemory::Free(scaledAlpha);
|
||||
mFlags = 0;
|
||||
}
|
||||
|
||||
@ -1221,7 +1245,7 @@ nsImageGTK::Draw(nsIRenderingContext &aContext,
|
||||
return NS_OK;
|
||||
|
||||
if ((mAlphaDepth==8) && mAlphaValid) {
|
||||
DrawComposited(aContext, aSurface, 0, 0, aX, aY, aWidth, aHeight);
|
||||
DrawComposited(aContext, aSurface, 0, 0, aWidth, aHeight, aX, aY, aWidth, aHeight);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -136,26 +136,31 @@ private:
|
||||
static unsigned scaled5[1<<5];
|
||||
|
||||
void DrawComposited32(PRBool isLSB, PRBool flipBytes,
|
||||
unsigned offsetX, unsigned offsetY,
|
||||
PRUint8 *imageOrigin, PRUint32 imageStride,
|
||||
PRUint8 *alphaOrigin, PRUint32 alphaStride,
|
||||
unsigned width, unsigned height,
|
||||
XImage *ximage, unsigned char *readData);
|
||||
void DrawComposited24(PRBool isLSB, PRBool flipBytes,
|
||||
unsigned offsetX, unsigned offsetY,
|
||||
PRUint8 *imageOrigin, PRUint32 imageStride,
|
||||
PRUint8 *alphaOrigin, PRUint32 alphaStride,
|
||||
unsigned width, unsigned height,
|
||||
XImage *ximage, unsigned char *readData);
|
||||
void DrawComposited16(PRBool isLSB, PRBool flipBytes,
|
||||
unsigned offsetX, unsigned offsetY,
|
||||
PRUint8 *imageOrigin, PRUint32 imageStride,
|
||||
PRUint8 *alphaOrigin, PRUint32 alphaStride,
|
||||
unsigned width, unsigned height,
|
||||
XImage *ximage, unsigned char *readData);
|
||||
void DrawCompositedGeneral(PRBool isLSB, PRBool flipBytes,
|
||||
unsigned offsetX, unsigned offsetY,
|
||||
PRUint8 *imageOrigin, PRUint32 imageStride,
|
||||
PRUint8 *alphaOrigin, PRUint32 alphaStride,
|
||||
unsigned width, unsigned height,
|
||||
XImage *ximage, unsigned char *readData);
|
||||
inline void DrawComposited(nsIRenderingContext &aContext,
|
||||
nsDrawingSurface aSurface,
|
||||
PRInt32 aSX, PRInt32 aSY,
|
||||
PRInt32 aSWidth, PRInt32 aSHeight,
|
||||
PRInt32 aDX, PRInt32 aDY,
|
||||
PRInt32 aWidth, PRInt32 aHeight);
|
||||
PRInt32 aDWidth, PRInt32 aDHeight);
|
||||
|
||||
inline void TilePixmap(GdkPixmap *src, GdkPixmap *dest, PRInt32 aSXOffset, PRInt32 aSYOffset,
|
||||
const nsRect &destRect, const nsRect &clipRect, PRBool useClip);
|
||||
|
@ -1,337 +0,0 @@
|
||||
/* -*- 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):
|
||||
* Syd Logan <syd@netscape.com>
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "drawers.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#include "nspr.h"
|
||||
|
||||
XImage *
|
||||
NNScaleImage(Display *display, XImage *img,
|
||||
double factorX, double factorY,
|
||||
PRInt32 aSWidth, PRInt32 aSHeight,
|
||||
PRInt32 newWidth, PRInt32 newHeight)
|
||||
{
|
||||
XImage *newImg;
|
||||
PRUint32 pixel;
|
||||
PRInt16 i, j, xsrc, ysrc;
|
||||
PRUint32 size;
|
||||
char *data;
|
||||
|
||||
|
||||
newImg = XCreateImage(display, DefaultVisual(display, 0),
|
||||
img->depth,
|
||||
img->format,
|
||||
0, 0, newWidth, newHeight,
|
||||
img->bitmap_pad, 0);
|
||||
|
||||
if (!newImg) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = newHeight * newImg->bytes_per_line;
|
||||
data = (char *) PR_Malloc(size);
|
||||
newImg->data = data;
|
||||
|
||||
if (!data) {
|
||||
XDestroyImage(newImg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (factorX == 1) {
|
||||
/* an obvious optimization is to bypass XPutPixel
|
||||
and to memcpy rows in img->data if factorX is 1
|
||||
*/
|
||||
|
||||
char *dptr, *sptr;
|
||||
PRUint32 rowsize;
|
||||
|
||||
dptr = newImg->data;
|
||||
rowsize = img->bytes_per_line;
|
||||
for (i = 0; i < newHeight; i++) {
|
||||
ysrc = (PRInt16) (i * factorY);
|
||||
sptr = img->data + ysrc * rowsize;
|
||||
memcpy(dptr, sptr, PR_MIN(rowsize, newImg->bytes_per_line));
|
||||
dptr += newImg->bytes_per_line;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < newWidth; i++) {
|
||||
xsrc = (PRInt16) (i * factorX);
|
||||
for (j = 0; j < newHeight; j++) {
|
||||
ysrc = (PRInt16) (j * factorY);
|
||||
pixel = XGetPixel(img, xsrc, ysrc);
|
||||
XPutPixel(newImg, i, j, pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
return newImg;
|
||||
}
|
||||
|
||||
|
||||
static PRBool
|
||||
DoScale(Display *aDisplay,
|
||||
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)
|
||||
{
|
||||
XImage *srcImg = (XImage*)NULL;
|
||||
XImage *dstImg = (XImage*)NULL;
|
||||
|
||||
double factorX = (double)aSrcWidth / (double)aDWidth;
|
||||
double factorY = (double)aSrcHeight / (double)aDHeight;
|
||||
|
||||
srcImg = XGetImage(aDisplay, aSrc,
|
||||
aSX, aSY, aSrcWidth, aSrcHeight,
|
||||
AllPlanes, ZPixmap);
|
||||
|
||||
if (!srcImg)
|
||||
return PR_FALSE;
|
||||
|
||||
dstImg = NNScaleImage(aDisplay, srcImg, factorX, factorY,
|
||||
aSWidth, aSHeight,
|
||||
aDWidth, aDHeight);
|
||||
|
||||
XDestroyImage(srcImg);
|
||||
srcImg = (XImage*)NULL;
|
||||
|
||||
if (!dstImg)
|
||||
return PR_FALSE;
|
||||
|
||||
XPutImage(aDisplay, aDest, aGC, dstImg,
|
||||
0, 0,
|
||||
aDX, aDY,
|
||||
aDWidth, aDHeight);
|
||||
|
||||
PR_Free(dstImg->data); /* we allocated data, don't let Xlib free */
|
||||
dstImg->data = (char *) NULL; /* setting NULL is important!! */
|
||||
|
||||
XDestroyImage(dstImg);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
DrawScaledImageNN(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 = (GdkPixmap*)NULL;
|
||||
|
||||
GdkGC *gc = (GdkGC*)NULL;
|
||||
|
||||
if (aSrcMask) {
|
||||
Drawable destMask;
|
||||
|
||||
alphaMask = gdk_pixmap_new(aSrcMask, aDWidth, aDHeight, 1);
|
||||
destMask = GDK_WINDOW_XWINDOW(alphaMask);
|
||||
|
||||
gc = gdk_gc_new(alphaMask);
|
||||
|
||||
DoScale(display,
|
||||
GDK_WINDOW_XWINDOW(alphaMask), /* dest */
|
||||
GDK_GC_XGC(gc),
|
||||
GDK_WINDOW_XWINDOW(aSrcMask), /* src */
|
||||
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, 0, 0);
|
||||
}
|
||||
|
||||
if (!gc) {
|
||||
gc = aGC;
|
||||
gdk_gc_ref(gc);
|
||||
}
|
||||
|
||||
DoScale(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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#define SCALE_SHIFT 16
|
||||
|
||||
static void
|
||||
pixops_scale_nearest (guchar *dest_buf,
|
||||
int render_x0,
|
||||
int render_y0,
|
||||
int render_x1,
|
||||
int render_y1,
|
||||
int dest_rowstride,
|
||||
int dest_channels,
|
||||
const guchar *src_buf,
|
||||
int src_width,
|
||||
int src_height,
|
||||
int src_rowstride,
|
||||
int src_channels,
|
||||
double scale_x,
|
||||
double scale_y)
|
||||
{
|
||||
int i, j;
|
||||
int x;
|
||||
int x_step = (1 << SCALE_SHIFT) / scale_x;
|
||||
int y_step = (1 << SCALE_SHIFT) / scale_y;
|
||||
|
||||
printf("%f,%f\n", scale_x, scale_y);
|
||||
|
||||
PR_ASSERT(src_channels == dest_channels);
|
||||
|
||||
for (i = 0; i < (render_y1 - render_y0); i++) {
|
||||
const guchar *src = src_buf + (((i + render_y0) * y_step + y_step / 2) >> SCALE_SHIFT) * src_rowstride;
|
||||
guchar *dest = dest_buf + i * dest_rowstride;
|
||||
|
||||
x = render_x0 * x_step + x_step / 2;
|
||||
|
||||
for (j=0; j < (render_x1 - render_x0); j++) {
|
||||
const guchar *p = src + (x >> SCALE_SHIFT) * src_channels;
|
||||
|
||||
dest[0] = p[0];
|
||||
dest[1] = p[1];
|
||||
dest[2] = p[2];
|
||||
|
||||
dest += dest_channels;
|
||||
x += x_step;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PRBool
|
||||
DrawScaledImageBitsNN(Display *display,
|
||||
GdkDrawable *aDest,
|
||||
GdkGC *aGC,
|
||||
const PRUint8 *aSrc,
|
||||
PRInt32 aBytesPerRow,
|
||||
const PRUint8 *aSrcMask,
|
||||
PRInt32 aSrcWidth,
|
||||
PRInt32 aSrcHeight,
|
||||
PRInt32 aSX,
|
||||
PRInt32 aSY,
|
||||
PRInt32 aSWidth,
|
||||
PRInt32 aSHeight,
|
||||
PRInt32 aDX,
|
||||
PRInt32 aDY,
|
||||
PRInt32 aDWidth,
|
||||
PRInt32 aDHeight)
|
||||
{
|
||||
const guchar *inBuffer = (const guchar*)aSrc;
|
||||
PRInt32 destBytesPerRow;
|
||||
PRInt32 size = 0;
|
||||
guchar *outBuffer = (guchar*)NULL;
|
||||
GdkGC *gc;
|
||||
|
||||
printf("scaling image from %dx%d to %dx%d\n", aSrcWidth, aSrcHeight, aDWidth, aDHeight);
|
||||
printf("source: (%d,%d) -- dest: (%d,%d)\n", aSX, aSY, aDX, aDY);
|
||||
|
||||
destBytesPerRow = (aDWidth * 24) >> 5;
|
||||
if ((aDWidth * 3) & 0x1F) {
|
||||
destBytesPerRow++;
|
||||
}
|
||||
destBytesPerRow <<= 2;
|
||||
|
||||
size = destBytesPerRow * aDHeight;
|
||||
|
||||
printf("making buffer for dest... %d bytes\n", size);
|
||||
|
||||
outBuffer = (guchar *)PR_Calloc(size, 1);
|
||||
if (!outBuffer)
|
||||
return PR_FALSE;
|
||||
|
||||
pixops_scale_nearest(outBuffer, /* out buffer */
|
||||
0, 0, /* dest_x, dest_y */
|
||||
aDWidth, aDHeight, /* dest_width, dest_height */
|
||||
destBytesPerRow, 3, /* dest_row_stride, dest_num_chans */
|
||||
inBuffer, /* in buffer */
|
||||
aSrcWidth, aSrcHeight, /* src_width, src_height */
|
||||
aBytesPerRow, 3, /* src_row_stride, src_num_chans */
|
||||
(double)aSrcWidth / (double)aDWidth, /* scale_x */
|
||||
(double)aSrcHeight / (double)aDHeight); /* scale_y */
|
||||
|
||||
|
||||
gc = gdk_gc_new(aDest);
|
||||
|
||||
gdk_draw_rgb_image(aDest, gc,
|
||||
aDX, aDY, aDWidth, aDHeight,
|
||||
GDK_RGB_DITHER_MAX,
|
||||
outBuffer, destBytesPerRow);
|
||||
gdk_gc_unref(gc);
|
||||
|
||||
PR_Free(outBuffer);
|
||||
|
||||
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
215
gfx/src/gtk/scale.cpp
Normal file
215
gfx/src/gtk/scale.cpp
Normal file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
* 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 Tomas Mšller
|
||||
* Portions created by Tomas Mšller are
|
||||
* Copyright (C) 2001 Tomas Mšller. Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Tomas Mšller
|
||||
* Tim Rowley <tor@cs.brown.edu>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "scale.h"
|
||||
|
||||
// Scaling code from Graphics Gems book III
|
||||
// http://www.acm.org/pubs/tog/GraphicsGems/gemsiii/fastBitmap.c
|
||||
//
|
||||
// License states - "All code here can be used without restrictions."
|
||||
// http://www.acm.org/pubs/tog/GraphicsGems/
|
||||
|
||||
/*
|
||||
Fast Bitmap Stretching
|
||||
Tomas Mšller
|
||||
*/
|
||||
|
||||
#define sign(x) ((x)>0 ? 1:-1)
|
||||
|
||||
void RectStretch(long xs1,long ys1,long xs2,long ys2,
|
||||
long xd1,long yd1,long xd2,long yd2,
|
||||
unsigned char *aSrcImage, unsigned aSrcStride,
|
||||
unsigned char *aDstImage, unsigned aDstStride,
|
||||
unsigned aDepth);
|
||||
|
||||
static void Stretch24(long x1,long x2,long y1,long y2,long yr,long yw,
|
||||
unsigned char *aSrcImage, unsigned aSrcStride,
|
||||
unsigned char *aDstImage, unsigned aDstStride);
|
||||
static void Stretch8(long x1,long x2,long y1,long y2,long yr,long yw,
|
||||
unsigned char *aSrcImage, unsigned aSrcStride,
|
||||
unsigned char *aDstImage, unsigned aDstStride);
|
||||
static void Stretch1(long x1,long x2,long y1,long y2,long yr,long yw,
|
||||
unsigned char *aSrcImage, unsigned aSrcStride,
|
||||
unsigned char *aDstImage, unsigned aDstStride);
|
||||
|
||||
/**********************************************************
|
||||
RectStretch enlarges or diminishes a source rectangle of a bitmap to
|
||||
a destination rectangle. The source rectangle is selected by the two
|
||||
points (xs1,ys1) and (xs2,ys2), and the destination rectangle by
|
||||
(xd1,yd1) and (xd2,yd2). Since readability of source-code is wanted,
|
||||
some optimizations have been left out for the reader: It's possible
|
||||
to read one line at a time, by first stretching in x-direction and
|
||||
then stretching that bitmap in y-direction.
|
||||
|
||||
Entry:
|
||||
xs1,ys1 - first point of source rectangle
|
||||
xs2,ys2 - second point of source rectangle
|
||||
xd1,yd1 - first point of destination rectangle
|
||||
xd2,yd2 - second point of destination rectangle
|
||||
**********************************************************/
|
||||
void
|
||||
RectStretch(long xs1,long ys1,long xs2,long ys2,
|
||||
long xd1,long yd1,long xd2,long yd2,
|
||||
unsigned char *aSrcImage, unsigned aSrcStride,
|
||||
unsigned char *aDstImage, unsigned aDstStride,
|
||||
unsigned aDepth)
|
||||
{
|
||||
long dx,dy,e,d,dx2;
|
||||
short sx,sy;
|
||||
void (*Stretch)(long x1,long x2,long y1,long y2,long yr,long yw,
|
||||
unsigned char *aSrcImage, unsigned aSrcStride,
|
||||
unsigned char *aDstImage, unsigned aDstStride);
|
||||
|
||||
// fprintf(stderr, "(%ld %ld)-(%ld %ld) (%ld %ld)-(%ld %ld) %d %d %d\n",
|
||||
// xs1, ys1, xs2, ys2, xd1, yd1, xd2, yd2,
|
||||
// aSrcStride, aDstStride, aDepth);
|
||||
|
||||
switch (aDepth) {
|
||||
case 24:
|
||||
Stretch = Stretch24;
|
||||
break;
|
||||
case 8:
|
||||
Stretch = Stretch8;
|
||||
break;
|
||||
case 1:
|
||||
Stretch = Stretch1;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
dx = abs((int)(yd2-yd1));
|
||||
dy = abs((int)(ys2-ys1));
|
||||
sx = sign(yd2-yd1);
|
||||
sy = sign(ys2-ys1);
|
||||
e = (dy<<1)-dx;
|
||||
dx2 = dx<<1;
|
||||
dy <<= 1;
|
||||
if (!dx2) dx2=1;
|
||||
for (d=0; d<=dx; d++) {
|
||||
Stretch(xd1,xd2,xs1,xs2,ys1,yd1,aSrcImage,aSrcStride,aDstImage,aDstStride);
|
||||
while (e>=0) {
|
||||
ys1 += sy;
|
||||
e -= dx2;
|
||||
}
|
||||
yd1 += sx;
|
||||
e += dy;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
Stretches a horizontal source line onto a horizontal destination
|
||||
line. Used by RectStretch.
|
||||
|
||||
Entry:
|
||||
x1,x2 - x-coordinates of the destination line
|
||||
y1,y2 - x-coordinates of the source line
|
||||
yr - y-coordinate of source line
|
||||
yw - y-coordinate of destination line
|
||||
**********************************************************/
|
||||
static void
|
||||
Stretch24(long x1,long x2,long y1,long y2,long yr,long yw,
|
||||
unsigned char *aSrcImage, unsigned aSrcStride,
|
||||
unsigned char *aDstImage, unsigned aDstStride)
|
||||
{
|
||||
long dx,dy,e,d,dx2;
|
||||
short sx,sy;
|
||||
unsigned char *src, *dst;
|
||||
dx = abs((int)(x2-x1));
|
||||
dy = abs((int)(y2-y1));
|
||||
sx = 3*sign(x2-x1);
|
||||
sy = 3*sign(y2-y1);
|
||||
e = (dy<<1)-dx;
|
||||
dx2 = dx<<1;
|
||||
dy <<= 1;
|
||||
src=aSrcImage+yr*aSrcStride+3*y1;
|
||||
dst=aDstImage+yw*aDstStride+3*x1;
|
||||
if (!dx2) dx2=1;
|
||||
for (d=0; d<=dx; d++) {
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[2];
|
||||
while (e>=0) {
|
||||
src += sy;
|
||||
e -= dx2;
|
||||
}
|
||||
dst += sx;
|
||||
e += dy;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Stretch8(long x1,long x2,long y1,long y2,long yr,long yw,
|
||||
unsigned char *aSrcImage, unsigned aSrcStride,
|
||||
unsigned char *aDstImage, unsigned aDstStride)
|
||||
{
|
||||
long dx,dy,e,d,dx2;
|
||||
short sx,sy;
|
||||
unsigned char *src, *dst;
|
||||
dx = abs((int)(x2-x1));
|
||||
dy = abs((int)(y2-y1));
|
||||
sx = sign(x2-x1);
|
||||
sy = sign(y2-y1);
|
||||
e = (dy<<1)-dx;
|
||||
dx2 = dx<<1;
|
||||
dy <<= 1;
|
||||
src=aSrcImage+yr*aSrcStride+y1;
|
||||
dst=aDstImage+yw*aDstStride+x1;
|
||||
if (!dx2) dx2=1;
|
||||
for (d=0; d<=dx; d++) {
|
||||
*dst = *src;
|
||||
while (e>=0) {
|
||||
src += sy;
|
||||
e -= dx2;
|
||||
}
|
||||
dst += sx;
|
||||
e += dy;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Stretch1(long x1,long x2,long y1,long y2,long yr,long yw,
|
||||
unsigned char *aSrcImage, unsigned aSrcStride,
|
||||
unsigned char *aDstImage, unsigned aDstStride)
|
||||
{
|
||||
long dx,dy,e,d,dx2;
|
||||
short sx,sy;
|
||||
dx = abs((int)(x2-x1));
|
||||
dy = abs((int)(y2-y1));
|
||||
sx = sign(x2-x1);
|
||||
sy = sign(y2-y1);
|
||||
e = (dy<<1)-dx;
|
||||
dx2 = dx<<1;
|
||||
dy <<= 1;
|
||||
if (!dx2) dx2=1;
|
||||
for (d=0; d<=dx; d++) {
|
||||
if (*(aSrcImage+yr*aSrcStride+(y1>>3)) & 1<<(7-y1&0x7))
|
||||
*(aDstImage+yw*aDstStride+(x1>>3)) |= 1<<(7-x1&0x7);
|
||||
while (e>=0) {
|
||||
y1 += sy;
|
||||
e -= dx2;
|
||||
}
|
||||
x1 += sx;
|
||||
e += dy;
|
||||
}
|
||||
}
|
27
gfx/src/gtk/scale.h
Normal file
27
gfx/src/gtk/scale.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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 Tomas Mšller
|
||||
* Portions created by Tomas Mšller are
|
||||
* Copyright (C) 2001 Tomas Mšller. Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Tomas Mšller
|
||||
* Tim Rowley <tor@cs.brown.edu>
|
||||
*/
|
||||
|
||||
void RectStretch(long xs1,long ys1,long xs2,long ys2,
|
||||
long xd1,long yd1,long xd2,long yd2,
|
||||
unsigned char *aSrcImage, unsigned aSrcStride,
|
||||
unsigned char *aDstImage, unsigned aDstStride,
|
||||
unsigned aDepth);
|
Loading…
x
Reference in New Issue
Block a user