Index: Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java,v retrieving revision 1.247 diff -u -r1.247 GC.java --- Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java 20 Nov 2008 16:18:21 -0000 1.247 +++ Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java 11 Dec 2008 14:38:12 -0000 @@ -83,7 +83,7 @@ static final int DRAW_OFFSET = 1 << 14; static final int DRAW = FOREGROUND | LINE_STYLE | LINE_WIDTH | LINE_CAP | LINE_JOIN | LINE_MITERLIMIT | PEN | NULL_BRUSH | DRAW_OFFSET; - static final int FILL = BACKGROUND | BRUSH | NULL_PEN; + static final int FILL = BACKGROUND | BRUSH | NULL_PEN | DRAW_OFFSET; static final float[] LINE_DOT_ZERO = new float[]{3, 3}; static final float[] LINE_DASH_ZERO = new float[]{18, 6}; @@ -227,7 +227,12 @@ case SWT.LINE_DASHDOTDOT: dashStyle = Gdip.DashStyleDashDotDot; if (width == 0) dashes = LINE_DASHDOTDOT_ZERO; break; case SWT.LINE_CUSTOM: { if (data.lineDashes != null) { - dashOffset = data.lineDashesOffset / Math.max (1, width); + dashOffset = data.lineDashesOffset; + if (data.pixelOffsetMode == SWT.PIXEL_OFFSET_COMPATIBILITY) { + if ((data.lineWidth % 2) == 1) + dashOffset += 0.5; + } + dashOffset = dashOffset / Math.max (1, width); dashes = new float[data.lineDashes.length * 2]; for (int i = 0; i < data.lineDashes.length; i++) { float dash = data.lineDashes[i] / Math.max (1, width); @@ -306,24 +311,12 @@ data.gdipFont = gdipFont; } if ((state & DRAW_OFFSET) != 0) { - data.gdipXOffset = data.gdipYOffset = 0; - int /*long*/ matrix = Gdip.Matrix_new(1, 0, 0, 1, 0, 0); - PointF point = new PointF(); - point.X = point.Y = 1; - Gdip.Graphics_GetTransform(gdipGraphics, matrix); - Gdip.Matrix_TransformVectors(matrix, point, 1); - Gdip.Matrix_delete(matrix); - float scaling = point.X; - if (scaling < 0) scaling = -scaling; - float penWidth = data.lineWidth * scaling; - if (penWidth == 0 || ((int)penWidth % 2) == 1) { - data.gdipXOffset = 0.5f / scaling; - } - scaling = point.Y; - if (scaling < 0) scaling = -scaling; - penWidth = data.lineWidth * scaling; - if (penWidth == 0 || ((int)penWidth % 2) == 1) { - data.gdipYOffset = 0.5f / scaling; + int lineWidth = (int) data.lineWidth; + data.gdipFillOffset = data.gdipOffset = 0; + if (data.pixelOffsetMode == SWT.PIXEL_OFFSET_COMPATIBILITY) { + data.gdipFillOffset = 0.5f; + if(lineWidth == 0 || (lineWidth % 2) == 1) + data.gdipOffset = 0.5f; } } return; @@ -706,7 +699,7 @@ if (width == 0 || height == 0 || arcAngle == 0) return; int /*long*/ gdipGraphics = data.gdipGraphics; if (gdipGraphics != 0) { - Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend); + gdipShift(FOREGROUND, data.gdipOffset); if (width == height) { Gdip.Graphics_DrawArc(gdipGraphics, data.gdipPen, x, y, width, height, -startAngle, -arcAngle); } else { @@ -720,7 +713,7 @@ Gdip.Matrix_delete(matrix); Gdip.GraphicsPath_delete(path); } - Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset, Gdip.MatrixOrderPrepend); + gdipShift(FOREGROUND, -data.gdipOffset); return; } if ((data.style & SWT.MIRRORED) != 0) { @@ -1629,9 +1622,9 @@ checkGC(DRAW); int /*long*/ gdipGraphics = data.gdipGraphics; if (gdipGraphics != 0) { - Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend); + gdipShift(FOREGROUND, data.gdipOffset); Gdip.Graphics_DrawLine(gdipGraphics, data.gdipPen, x1, y1, x2, y2); - Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset, Gdip.MatrixOrderPrepend); + gdipShift(FOREGROUND, -data.gdipOffset); return; } if ((data.style & SWT.MIRRORED) != 0) { @@ -1678,9 +1671,9 @@ checkGC(DRAW); int /*long*/ gdipGraphics = data.gdipGraphics; if (gdipGraphics != 0) { - Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend); + gdipShift(FOREGROUND, data.gdipOffset); Gdip.Graphics_DrawEllipse(gdipGraphics, data.gdipPen, x, y, width, height); - Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset, Gdip.MatrixOrderPrepend); + gdipShift(FOREGROUND, -data.gdipOffset); return; } if ((data.style & SWT.MIRRORED) != 0) { @@ -1718,10 +1711,7 @@ if (path.handle == 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); initGdip(); checkGC(DRAW); - int /*long*/ gdipGraphics = data.gdipGraphics; - Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend); - Gdip.Graphics_DrawPath(gdipGraphics, data.gdipPen, path.handle); - Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset, Gdip.MatrixOrderPrepend); + Gdip.Graphics_DrawPath(data.gdipGraphics, data.gdipPen, path.handle); } /** @@ -1774,9 +1764,9 @@ checkGC(DRAW); int /*long*/ gdipGraphics = data.gdipGraphics; if (gdipGraphics != 0) { - Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend); + gdipShift(FOREGROUND, data.gdipOffset); Gdip.Graphics_DrawPolygon(gdipGraphics, data.gdipPen, pointArray, pointArray.length / 2); - Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset, Gdip.MatrixOrderPrepend); + gdipShift(FOREGROUND, -data.gdipOffset); return; } if ((data.style & SWT.MIRRORED) != 0) { @@ -1819,9 +1809,9 @@ checkGC(DRAW); int /*long*/ gdipGraphics = data.gdipGraphics; if (gdipGraphics != 0) { - Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend); + gdipShift(FOREGROUND, data.gdipOffset); Gdip.Graphics_DrawLines(gdipGraphics, data.gdipPen, pointArray, pointArray.length / 2); - Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset, Gdip.MatrixOrderPrepend); + gdipShift(FOREGROUND, -data.gdipOffset); return; } if ((data.style & SWT.MIRRORED) != 0) { @@ -1875,9 +1865,9 @@ y = y + height; height = -height; } - Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend); + gdipShift(FOREGROUND, data.gdipOffset); Gdip.Graphics_DrawRectangle(gdipGraphics, data.gdipPen, x, y, width, height); - Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset, Gdip.MatrixOrderPrepend); + gdipShift(FOREGROUND, -data.gdipOffset); return; } if ((data.style & SWT.MIRRORED) != 0) { @@ -1992,8 +1982,8 @@ } void drawRoundRectangleGdip (int /*long*/ gdipGraphics, int /*long*/ pen, int x, int y, int width, int height, int arcWidth, int arcHeight) { - int nx = x; - int ny = y; + float nx = x; + float ny = y; int nw = width; int nh = height; int naw = arcWidth; @@ -2012,10 +2002,13 @@ if (nah < 0) nah = 0 - nah; - Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend); if (naw == 0 || nah == 0) { + gdipShift(FOREGROUND, data.gdipOffset); Gdip.Graphics_DrawRectangle(gdipGraphics, data.gdipPen, x, y, width, height); + gdipShift(FOREGROUND, -data.gdipOffset); } else { + nx += data.gdipOffset; + ny += data.gdipOffset; int /*long*/ path = Gdip.GraphicsPath_new(Gdip.FillModeAlternate); if (path == 0) SWT.error(SWT.ERROR_NO_HANDLES); if (nw > naw) { @@ -2040,7 +2033,6 @@ Gdip.Graphics_DrawPath(gdipGraphics, pen, path); Gdip.GraphicsPath_delete(path); } - Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset, Gdip.MatrixOrderPrepend); } /** @@ -2773,7 +2765,9 @@ checkGC(FILL); if (data.gdipGraphics != 0) { int mode = OS.GetPolyFillMode(handle) == OS.WINDING ? Gdip.FillModeWinding : Gdip.FillModeAlternate; + gdipShift(BACKGROUND, data.gdipFillOffset); Gdip.Graphics_FillPolygon(data.gdipGraphics, data.gdipBrush, pointArray, pointArray.length / 2, mode); + gdipShift(BACKGROUND, -data.gdipFillOffset); return; } if ((data.style & SWT.MIRRORED) != 0) { @@ -2933,7 +2927,7 @@ Gdip.Graphics_Flush(data.gdipGraphics, 0); /* * Note Flush() does not flush the output to the - * underline HDC. This is done by calling GetHDC() + * underlying HDC. This is done by calling GetHDC() * followed by ReleaseHDC(). */ int /*long*/ hdc = Gdip.Graphics_GetHDC(data.gdipGraphics); @@ -2941,6 +2935,28 @@ } } +void gdipShift(int flags, float amount) { + if (amount == 0) + return; + Gdip.Graphics_TranslateTransform(data.gdipGraphics, amount, amount, Gdip.MatrixOrderPrepend); + if ((flags & FOREGROUND) != 0 && data.foregroundPattern != null) + gdipShiftBrush(data.gdipFgBrush, -amount); + if ((flags & BACKGROUND) != 0 && data.backgroundPattern != null) + gdipShiftBrush(data.gdipBgBrush, -amount); +} + +void gdipShiftBrush(int brush, float amount) { + switch (Gdip.Brush_GetType(brush)) { + case Gdip.BrushTypeTextureFill: + Gdip.TextureBrush_TranslateTransform(brush, amount, amount, Gdip.MatrixOrderPrepend); + Gdip.Pen_SetBrush(data.gdipPen, brush); + break; + case Gdip.BrushTypeLinearGradient: + Gdip.LinearGradientBrush_TranslateTransform(brush, amount, amount, Gdip.MatrixOrderPrepend); + break; + } +} + /** * Returns the advance width of the specified character in * the font which is currently selected into the receiver. @@ -3586,7 +3602,6 @@ if (transform.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); int /*long*/ gdipGraphics = data.gdipGraphics; if (gdipGraphics != 0) { - Gdip.Graphics_GetTransform(gdipGraphics, transform.handle); int /*long*/ identity = identity(); Gdip.Matrix_Invert(identity); Gdip.Matrix_Multiply(transform.handle, identity, Gdip.MatrixOrderAppend); @@ -4583,6 +4598,12 @@ data.state &= ~(LINE_WIDTH | DRAW_OFFSET); } +public void setPixelOffsetMode(int offsetMode) { + if (data.pixelOffsetMode == offsetMode) + return; + data.state &= ~DRAW_OFFSET; +} + /** * If the argument is true, puts the receiver * in a drawing mode where the resulting color in the destination @@ -4697,11 +4718,10 @@ initGdip(); int /*long*/ identity = identity(); if (transform != null) { - Gdip.Matrix_Multiply(identity, transform.handle, Gdip.MatrixOrderPrepend); + Gdip.Matrix_Multiply(identity, transform.handle, Gdip.MatrixOrderPrepend); } Gdip.Graphics_SetTransform(data.gdipGraphics, identity); Gdip.Matrix_delete(identity); - data.state &= ~DRAW_OFFSET; } /** Index: Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java,v retrieving revision 1.27 diff -u -r1.27 GCData.java --- Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java 9 Oct 2008 21:57:11 -0000 1.27 +++ Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java 11 Dec 2008 14:38:13 -0000 @@ -42,6 +42,9 @@ public float[] lineDashes; public float lineMiterLimit = 10; public int alpha = 0xFF; + public int pixelOffsetMode = SWT.PIXEL_OFFSET_COMPATIBILITY; + public float gdipOffset; + public float gdipFillOffset; public Image image; public int /*long*/ hPen, hOldPen; @@ -57,7 +60,6 @@ public int /*long*/ gdipBgBrush; public int /*long*/ gdipFont; public int /*long*/ hGDIFont; - public float gdipXOffset, gdipYOffset; public int uiState = 0; public boolean focusDrawn; }