Hi,
The attached patch gets cairo to respect interpolation hints; however
I'm not entirely convinced it's the best option. I don't want to remove
the cairoSurfaceSetFilter function; however the cairo_pattern usually
hasn't been created yet (and won't be created until the drawPixels or
drawSurface function), so I'm not sure how to make SurfaceSetFilter do
anything useful...
Any thoughts on this, or should I just commit it?
Thanks,
Francis
Index: native/jni/gtk-peer/cairographics2d.h
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/gtk-peer/cairographics2d.h,v
retrieving revision 1.4
diff -u -r1.4 cairographics2d.h
--- native/jni/gtk-peer/cairographics2d.h 10 Jun 2006 14:16:09 -0000 1.4
+++ native/jni/gtk-peer/cairographics2d.h 6 Sep 2006 20:57:03 -0000
@@ -97,7 +97,8 @@
java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR = 1,
java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED = 2,
java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY = 3,
- java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT = 4
+ java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT = 4,
+ java_awt_rendering_hints_VALUE_INTERPOLATION_BICUBIC = 5
};
Index: native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c,v
retrieving revision 1.20
diff -u -r1.20 gnu_java_awt_peer_gtk_CairoSurface.c
--- native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c 13 Jun 2006 15:59:36 -0000 1.20
+++ native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c 6 Sep 2006 20:57:03 -0000
@@ -181,7 +181,8 @@
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_CairoSurface_nativeDrawSurface
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
- jlong surfacePointer, jlong context, jdoubleArray java_matrix, double alpha)
+ jlong surfacePointer, jlong context, jdoubleArray java_matrix, double alpha,
+ jint interpolation)
{
struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, context);
cairo_t *cr = gr->cr;
@@ -205,6 +206,27 @@
p = cairo_pattern_create_for_surface (surface);
cairo_pattern_set_matrix (p, &mat);
+ switch ((enum java_awt_rendering_hints_filter) interpolation)
+ {
+ case java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR:
+ cairo_pattern_set_filter (p, CAIRO_FILTER_NEAREST);
+ break;
+ case java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR:
+ cairo_pattern_set_filter (p, CAIRO_FILTER_BILINEAR);
+ break;
+ case java_awt_rendering_hints_VALUE_INTERPOLATION_BICUBIC:
+ cairo_pattern_set_filter (p, CAIRO_FILTER_GAUSSIAN);
+ break;
+ case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED:
+ cairo_pattern_set_filter (p, CAIRO_FILTER_FAST);
+ break;
+ case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT:
+ cairo_pattern_set_filter (p, CAIRO_FILTER_NEAREST);
+ break;
+ case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY:
+ cairo_pattern_set_filter (p, CAIRO_FILTER_BEST);
+ break;
+ }
cairo_set_source(cr, p);
if (alpha == 1.0)
Index: native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c,v
retrieving revision 1.14
diff -u -r1.14 gnu_java_awt_peer_gtk_CairoGraphics2D.c
--- native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c 6 Aug 2006 21:00:54 -0000 1.14
+++ native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c 6 Sep 2006 20:57:03 -0000
@@ -138,6 +138,9 @@
cairo_pattern_set_extend( pattern, extend );
+ if (gr->pattern != NULL)
+ cairo_pattern_set_filter (pattern, cairo_pattern_get_filter (gr->pattern));
+
gr->pattern = pattern;
cairo_set_source(gr->cr, gr->pattern);
}
@@ -178,6 +181,7 @@
CAIRO_FORMAT_ARGB32,
w, h, stride * 4);
g_assert (gr->pattern_surface != NULL);
+
gr->pattern = cairo_pattern_create_for_surface (gr->pattern_surface);
g_assert (gr->pattern != NULL);
cairo_pattern_set_extend (gr->pattern, CAIRO_EXTEND_REPEAT);
@@ -188,7 +192,8 @@
Java_gnu_java_awt_peer_gtk_CairoGraphics2D_drawPixels
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
jlong pointer, jintArray java_pixels,
- jint w, jint h, jint stride, jdoubleArray java_matrix, jdouble alpha)
+ jint w, jint h, jint stride, jdoubleArray java_matrix, jdouble alpha,
+ jint interpolation)
{
jint *native_pixels = NULL;
jdouble *native_matrix = NULL;
@@ -215,8 +220,28 @@
p = cairo_pattern_create_for_surface (surf);
cairo_pattern_set_matrix (p, &mat);
- if (gr->pattern)
- cairo_pattern_set_filter (p, cairo_pattern_get_filter (gr->pattern));
+ switch ((enum java_awt_rendering_hints_filter) interpolation)
+ {
+ case java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR:
+ cairo_pattern_set_filter (p, CAIRO_FILTER_NEAREST);
+ break;
+ case java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR:
+ cairo_pattern_set_filter (p, CAIRO_FILTER_BILINEAR);
+ break;
+ case java_awt_rendering_hints_VALUE_INTERPOLATION_BICUBIC:
+ cairo_pattern_set_filter (p, CAIRO_FILTER_GAUSSIAN);
+ break;
+ case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED:
+ cairo_pattern_set_filter (p, CAIRO_FILTER_FAST);
+ break;
+ case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT:
+ cairo_pattern_set_filter (p, CAIRO_FILTER_NEAREST);
+ break;
+ case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY:
+ cairo_pattern_set_filter (p, CAIRO_FILTER_BEST);
+ break;
+ }
+
cairo_set_source (gr->cr, p);
if (alpha == 1.)
cairo_paint (gr->cr);
@@ -679,37 +704,6 @@
}
JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSurfaceSetFilter
-(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
- jlong pointer, jint filter)
-{
- struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
- g_assert (gr != NULL);
-
- if (gr->pattern == NULL)
- return;
-
- switch ((enum java_awt_rendering_hints_filter) filter)
- {
- case java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR:
- cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_NEAREST);
- break;
- case java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR:
- cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_BILINEAR);
- break;
- case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED:
- cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_FAST);
- break;
- case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT:
- cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_NEAREST);
- break;
- case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY:
- cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_BEST);
- break;
- }
-}
-
-JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoDrawLine
(JNIEnv *env __attribute__ ((unused)), jobject obj __attribute__ ((unused)),
jlong pointer, jdouble x1, jdouble y1, jdouble x2, jdouble y2)
Index: gnu/java/awt/peer/gtk/CairoSurface.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/CairoSurface.java,v
retrieving revision 1.16
diff -u -r1.16 CairoSurface.java
--- gnu/java/awt/peer/gtk/CairoSurface.java 8 Aug 2006 22:30:52 -0000 1.16
+++ gnu/java/awt/peer/gtk/CairoSurface.java 6 Sep 2006 20:57:03 -0000
@@ -102,11 +102,13 @@
* with an affine transform given by i2u.
*/
public native void nativeDrawSurface(long surfacePointer, long contextPointer,
- double[] i2u, double alpha);
+ double[] i2u, double alpha,
+ int interpolation);
- public void drawSurface(long contextPointer, double[] i2u, double alpha)
+ public void drawSurface(long contextPointer, double[] i2u, double alpha,
+ int interpolation)
{
- nativeDrawSurface(surfacePointer, contextPointer, i2u, alpha);
+ nativeDrawSurface(surfacePointer, contextPointer, i2u, alpha, interpolation);
}
/**
Index: gnu/java/awt/peer/gtk/CairoGraphics2D.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java,v
retrieving revision 1.37
diff -u -r1.37 CairoGraphics2D.java
--- gnu/java/awt/peer/gtk/CairoGraphics2D.java 8 Aug 2006 22:30:52 -0000 1.37
+++ gnu/java/awt/peer/gtk/CairoGraphics2D.java 6 Sep 2006 20:57:03 -0000
@@ -309,7 +309,8 @@
* @param i2u - affine transform array
*/
private native void drawPixels(long pointer, int[] pixels, int w, int h,
- int stride, double[] i2u, double alpha);
+ int stride, double[] i2u, double alpha,
+ int interpolation);
private native void setGradient(long pointer, double x1, double y1,
double x2, double y2,
@@ -441,11 +442,6 @@
private native void cairoResetClip(long pointer);
/**
- * Set interpolation types
- */
- private native void cairoSurfaceSetFilter(long pointer, int filter);
-
- /**
* Draws a line from (x1,y1) to (x2,y2).
*
* @param pointer the native pointer
@@ -1150,32 +1146,10 @@
///////////////////////// RENDERING HINTS ///////////////////////////////////
- /**
- * FIXME- support better
- */
public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue)
{
hints.put(hintKey, hintValue);
- if (hintKey.equals(RenderingHints.KEY_INTERPOLATION)
- || hintKey.equals(RenderingHints.KEY_ALPHA_INTERPOLATION))
- {
- if (hintValue.equals(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR))
- cairoSurfaceSetFilter(nativePointer, 0);
-
- else if (hintValue.equals(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
- cairoSurfaceSetFilter(nativePointer, 1);
-
- else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED))
- cairoSurfaceSetFilter(nativePointer, 2);
-
- else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY))
- cairoSurfaceSetFilter(nativePointer, 3);
-
- else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT))
- cairoSurfaceSetFilter(nativePointer, 4);
- }
-
shiftDrawCalls = hints.containsValue(RenderingHints.VALUE_STROKE_NORMALIZE)
|| hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT);
}
@@ -1189,28 +1163,7 @@
{
this.hints = new RenderingHints(getDefaultHints());
this.hints.add(new RenderingHints(hints));
-
- if (hints.containsKey(RenderingHints.KEY_INTERPOLATION))
- {
- if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR))
- cairoSurfaceSetFilter(nativePointer, 0);
-
- else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
- cairoSurfaceSetFilter(nativePointer, 1);
- }
-
- if (hints.containsKey(RenderingHints.KEY_ALPHA_INTERPOLATION))
- {
- if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED))
- cairoSurfaceSetFilter(nativePointer, 2);
-
- else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY))
- cairoSurfaceSetFilter(nativePointer, 3);
-
- else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT))
- cairoSurfaceSetFilter(nativePointer, 4);
- }
-
+
shiftDrawCalls = hints.containsValue(RenderingHints.VALUE_STROKE_NORMALIZE)
|| hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT);
}
@@ -1224,6 +1177,31 @@
{
return hints;
}
+
+ private int getInterpolation()
+ {
+ if (this.hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR))
+ return 0; // CAIRO_FILTER_NEAREST
+
+ else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
+ return 1; // CAIRO_FILTER_BILINEAR
+
+ else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BICUBIC))
+ return 5; // CAIRO_FILTER_GAUSSIAN
+
+ // TODO: Does ALPHA_INTERPOLATION really correspond to CAIRO_FILTER_FAST/BEST/GOOD?
+ else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED))
+ return 2; // CAIRO_FILTER_FAST
+
+ else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY))
+ return 3; // CAIRO_FILTER_BEST
+
+ else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT))
+ return 4; // CAIRO_FILTER_GOOD
+
+ // Do bilinear interpolation as default
+ return 1;
+ }
///////////////////////// IMAGE. METHODS ///////////////////////////////////
@@ -1290,7 +1268,8 @@
if(raster instanceof CairoSurface)
{
- ((CairoSurface)raster).drawSurface(nativePointer, i2u, alpha);
+ ((CairoSurface)raster).drawSurface(nativePointer, i2u, alpha,
+ getInterpolation());
updateColor();
return true;
}
@@ -1310,7 +1289,8 @@
int[] pixels = b.getRGB(0, 0, width, height, null, 0, width);
- drawPixels(nativePointer, pixels, width, height, width, i2u, alpha);
+ drawPixels(nativePointer, pixels, width, height, width, i2u, alpha,
+ getInterpolation());
// Cairo seems to lose the current color which must be restored.
updateColor();
@@ -1626,7 +1606,7 @@
if (comp instanceof AlphaComposite)
alpha = ((AlphaComposite) comp).getAlpha();
drawPixels(nativePointer, pixels, r.getWidth(), r.getHeight(),
- r.getWidth(), i2u, alpha);
+ r.getWidth(), i2u, alpha, getInterpolation());
// Cairo seems to lose the current color which must be restored.
updateColor();