javauis/eswt_qt/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/graphics/GC.java
changeset 21 2a9601315dfc
child 35 85266cc22c7f
equal deleted inserted replaced
18:e8e63152f320 21:2a9601315dfc
       
     1 /*******************************************************************************
       
     2  * Copyright (c) 2000, 2007 IBM Corporation and others.
       
     3  * Portion Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     4  * All rights reserved. This program and the accompanying materials
       
     5  * are made available under the terms of the Eclipse Public License v1.0
       
     6  * which accompanies this distribution, and is available at
       
     7  * http://www.eclipse.org/legal/epl-v10.html
       
     8  *
       
     9  * Contributors:
       
    10  *     IBM Corporation - initial API and implementation
       
    11  *     Nokia Corporation - Qt implementation
       
    12  *******************************************************************************/
       
    13 package org.eclipse.swt.graphics;
       
    14 
       
    15 import org.eclipse.swt.SWT;
       
    16 import org.eclipse.swt.internal.qt.GCData;
       
    17 import org.eclipse.swt.internal.qt.OS;
       
    18 import org.eclipse.swt.internal.qt.graphics.GraphicsContext;
       
    19 import org.eclipse.swt.widgets.Control;
       
    20 import org.eclipse.swt.widgets.Display;
       
    21 
       
    22 /**
       
    23  * Class <code>GC</code> is where all of the drawing capabilities that are
       
    24  * supported by SWT are located. Instances are used to draw on either an
       
    25  * <code>Image</code>, a <code>Control</code>, or directly on a
       
    26  * <code>Display</code>.
       
    27  * <dl>
       
    28  * <dt><b>Styles:</b></dt>
       
    29  * <dd>LEFT_TO_RIGHT, RIGHT_TO_LEFT</dd>
       
    30  * </dl>
       
    31  * 
       
    32  * <p>
       
    33  * The SWT drawing coordinate system is the two-dimensional space with the
       
    34  * origin (0,0) at the top left corner of the drawing area and with (x,y) values
       
    35  * increasing to the right and downward respectively.
       
    36  * </p>
       
    37  * 
       
    38  * <p>
       
    39  * Application code must explicitly invoke the <code>GC.dispose()</code> method
       
    40  * to release the operating system resources managed by each instance when those
       
    41  * instances are no longer required. This is <em>particularly</em> important on
       
    42  * Windows95 and Windows98 where the operating system has a limited number of
       
    43  * device contexts available.
       
    44  * </p>
       
    45  * 
       
    46  * <p>
       
    47  * Note: Only one of LEFT_TO_RIGHT and RIGHT_TO_LEFT may be specified.
       
    48  * </p>
       
    49  * 
       
    50  * @see org.eclipse.swt.events.PaintEvent
       
    51  */
       
    52 public final class GC {
       
    53 
       
    54 // FontMetrics
       
    55 private final static int FM_ASCENT = 0;
       
    56 private final static int FM_AVERAGE_CHAR_WIDTH = 1;
       
    57 private final static int FM_DESCENT = 2;
       
    58 private final static int FM_HEIGHT = 3;
       
    59 private final static int FM_LEADING = 4;
       
    60 private final static int FM_DATA_COUNT = 5;
       
    61 
       
    62 // Configuration flags
       
    63 final static int FOREGROUND = 1 << 0;
       
    64 final static int BACKGROUND = 1 << 1;
       
    65 final static int FONT = 1 << 2;
       
    66 final static int LINE_STYLE = 1 << 3;
       
    67 final static int LINE_CAP = 1 << 4;
       
    68 final static int LINE_JOIN = 1 << 5;
       
    69 final static int LINE_WIDTH = 1 << 6;
       
    70 final static int LINE_MITERLIMIT = 1 << 7;
       
    71 final static int BACKGROUND_BG = 1 << 8;
       
    72 final static int DRAW_OFFSET = 1 << 9;
       
    73 final static int DRAW = FOREGROUND | LINE_WIDTH | LINE_STYLE | LINE_CAP
       
    74         | LINE_JOIN | LINE_MITERLIMIT | DRAW_OFFSET;
       
    75 final static int FILL = BACKGROUND;
       
    76 
       
    77 static int checkStyle(int style) {
       
    78     if ((style & SWT.LEFT_TO_RIGHT) != 0) {
       
    79         style &= ~SWT.RIGHT_TO_LEFT;
       
    80     }
       
    81     return style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
       
    82 }
       
    83 
       
    84 int handle;
       
    85 GCData data;
       
    86 Color customForeground;
       
    87 Color customBackground;
       
    88 
       
    89 Drawable drawable;
       
    90 
       
    91 /**
       
    92  * Prevents uninitialized instances from being created outside the package.
       
    93  */
       
    94 GC() {
       
    95 }
       
    96 
       
    97 /**
       
    98  * Constructs a new instance of this class which has been configured to draw on
       
    99  * the specified drawable. Sets the foreground color, background color and font
       
   100  * in the GC to match those in the drawable.
       
   101  * <p>
       
   102  * You must dispose the graphics context when it is no longer required.
       
   103  * </p>
       
   104  * 
       
   105  * @param drawable
       
   106  *            the drawable to draw on
       
   107  * @exception IllegalArgumentException
       
   108  *                <ul>
       
   109  *                <li>ERROR_NULL_ARGUMENT - if the drawable is null</li>
       
   110  *                <li>ERROR_NULL_ARGUMENT - if there is no current device</li>
       
   111  *                <li>ERROR_INVALID_ARGUMENT - if the drawable is an image that
       
   112  *                is not a bitmap or an icon - if the drawable is an image or
       
   113  *                printer that is already selected into another graphics context
       
   114  *                </li>
       
   115  *                </ul>
       
   116  * @exception SWTError
       
   117  *                <ul>
       
   118  *                <li>ERROR_NO_HANDLES if a handle could not be obtained for GC
       
   119  *                creation</li>
       
   120  *                <li>ERROR_THREAD_INVALID_ACCESS if not called from the thread
       
   121  *                that created the drawable</li>
       
   122  *                </ul>
       
   123  */
       
   124 public GC(Drawable drawable) {
       
   125     this(drawable, 0);
       
   126 }
       
   127 
       
   128 /**
       
   129  * Constructs a new instance of this class which has been configured to draw on
       
   130  * the specified drawable. Sets the foreground color, background color and font
       
   131  * in the GC to match those in the drawable.
       
   132  * <p>
       
   133  * You must dispose the graphics context when it is no longer required.
       
   134  * </p>
       
   135  * 
       
   136  * @param drawable
       
   137  *            the drawable to draw on
       
   138  * @param style
       
   139  *            the style of GC to construct
       
   140  * 
       
   141  * @exception IllegalArgumentException
       
   142  *                <ul>
       
   143  *                <li>ERROR_NULL_ARGUMENT - if the drawable is null</li>
       
   144  *                <li>ERROR_NULL_ARGUMENT - if there is no current device</li>
       
   145  *                <li>ERROR_INVALID_ARGUMENT - if the drawable is an image that
       
   146  *                is not a bitmap or an icon - if the drawable is an image or
       
   147  *                printer that is already selected into another graphics context
       
   148  *                </li>
       
   149  *                </ul>
       
   150  * @exception SWTError
       
   151  *                <ul>
       
   152  *                <li>ERROR_NO_HANDLES if a handle could not be obtained for GC
       
   153  *                creation</li>
       
   154  *                <li>ERROR_THREAD_INVALID_ACCESS if not called from the thread
       
   155  *                that created the drawable</li>
       
   156  *                </ul>
       
   157  * 
       
   158  */
       
   159 public GC(Drawable drawable, int style) {
       
   160     if (drawable == null) {
       
   161         SWT.error(SWT.ERROR_NULL_ARGUMENT);
       
   162     }
       
   163 
       
   164     GCData data = new GCData();
       
   165     data.style = checkStyle(style);
       
   166 
       
   167     int gcHandle = drawable.internal_new_GC(data);
       
   168     try {
       
   169         init(drawable, data, gcHandle);
       
   170     } catch (Error e) {
       
   171         drawable.internal_dispose_GC(data);
       
   172         throw e;
       
   173     }
       
   174 }
       
   175 
       
   176 /*
       
   177  * Here it's checked based on the data.state flags which gc attributes need to
       
   178  * be configured. State flags are set when configuration is up-to-date and
       
   179  * cleared when configuration is invalidated.
       
   180  */
       
   181 void checkGC(int mask) {
       
   182     int state = data.state;
       
   183     if ((state & mask) == mask)
       
   184         return;
       
   185     state = (state ^ mask) & mask; // take out bits not in mask
       
   186     data.state |= mask;
       
   187 
       
   188     if((data.state & FOREGROUND) != 0) {
       
   189         if ((data.style & SWT.MIRRORED) != 0) {
       
   190             int width = OS.QPaintDevice_width(data.drawable);
       
   191             data.internalGc.resetTransform();
       
   192             data.internalGc.translate(width - 1, 0);
       
   193             data.internalGc.scale(-1, 1);
       
   194         }
       
   195     }
       
   196 }
       
   197 
       
   198 /**
       
   199  * Copies a rectangular area of the receiver at the specified position into the
       
   200  * image, which must be of type <code>SWT.BITMAP</code>.
       
   201  * 
       
   202  * @param image
       
   203  *            the image to copy into
       
   204  * @param x
       
   205  *            the x coordinate in the receiver of the area to be copied
       
   206  * @param y
       
   207  *            the y coordinate in the receiver of the area to be copied
       
   208  * 
       
   209  * @exception IllegalArgumentException
       
   210  *                <ul>
       
   211  *                <li>ERROR_NULL_ARGUMENT - if the image is null</li>
       
   212  *                <li>ERROR_INVALID_ARGUMENT - if the image is not a bitmap or
       
   213  *                has been disposed</li>
       
   214  *                </ul>
       
   215  * @exception SWTException
       
   216  *                <ul>
       
   217  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
   218  *                </li>
       
   219  *                </ul>
       
   220  */
       
   221 public void copyArea(Image image, int x, int y) {
       
   222     if (handle == 0) {
       
   223         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
   224     }
       
   225     if (image == null) {
       
   226         SWT.error(SWT.ERROR_NULL_ARGUMENT);
       
   227     }
       
   228     if (image.type != SWT.BITMAP || image.isDisposed()) {
       
   229         SWT.error(SWT.ERROR_INVALID_ARGUMENT);
       
   230     }
       
   231 
       
   232     // Reset all mirroring transformation and calculate the mirrored coordinates
       
   233     // manually.
       
   234     if ((data.style & SWT.MIRRORED) != 0) {
       
   235         data.internalGc.resetTransform();
       
   236         data.state = ~FOREGROUND;
       
   237         int clientWidth = OS.QPaintDevice_width(data.drawable);
       
   238         x = clientWidth - x - image.getBounds().width;
       
   239     }
       
   240 
       
   241     data.internalGc.copyArea(image.getImage(), x, y);
       
   242 }
       
   243 
       
   244 /**
       
   245  * Copies a rectangular area of the receiver at the source position onto the
       
   246  * receiver at the destination position.
       
   247  * 
       
   248  * @param srcX
       
   249  *            the x coordinate in the receiver of the area to be copied
       
   250  * @param srcY
       
   251  *            the y coordinate in the receiver of the area to be copied
       
   252  * @param width
       
   253  *            the width of the area to copy
       
   254  * @param height
       
   255  *            the height of the area to copy
       
   256  * @param destX
       
   257  *            the x coordinate in the receiver of the area to copy to
       
   258  * @param destY
       
   259  *            the y coordinate in the receiver of the area to copy to
       
   260  * 
       
   261  * @exception SWTException
       
   262  *                <ul>
       
   263  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
   264  *                </li>
       
   265  *                </ul>
       
   266  */
       
   267 public void copyArea(int srcX, int srcY, int width, int height, int destX,
       
   268         int destY) {
       
   269     copyArea(srcX, srcY, width, height, destX, destY, true);
       
   270 }
       
   271 
       
   272 /**
       
   273  * Copies a rectangular area of the receiver at the source
       
   274  * position onto the receiver at the destination position.
       
   275  *
       
   276  * @param srcX the x coordinate in the receiver of the area to be copied
       
   277  * @param srcY the y coordinate in the receiver of the area to be copied
       
   278  * @param width the width of the area to copy
       
   279  * @param height the height of the area to copy
       
   280  * @param destX the x coordinate in the receiver of the area to copy to
       
   281  * @param destY the y coordinate in the receiver of the area to copy to
       
   282  * @param paint if <code>true</code> paint events will be generated for old and obscured areas
       
   283  *
       
   284  * @exception SWTException <ul>
       
   285  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
       
   286  * </ul>
       
   287  * 
       
   288  * @since 3.1 
       
   289  */
       
   290 public void copyArea(int srcX, int srcY, int width, int height, int destX, int destY, boolean paint) {
       
   291     if (handle == 0) {
       
   292         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
   293     }
       
   294     if (width <= 0 || height <= 0) {
       
   295         return;
       
   296     }
       
   297     int deltaX = destX - srcX;
       
   298     int deltaY = destY - srcY;
       
   299     if (deltaX == 0 && deltaY == 0) {
       
   300         return;
       
   301     }
       
   302 
       
   303     // Reset all mirroring transformation and calculate the mirrored coordinates
       
   304     // manually.
       
   305     if ((data.style & SWT.MIRRORED) != 0) {
       
   306         data.internalGc.resetTransform();
       
   307         data.state = ~FOREGROUND;
       
   308         int clientWidth = OS.QPaintDevice_width(data.drawable);
       
   309         srcX = clientWidth - srcX - width;
       
   310         destX = clientWidth - destX - width;
       
   311     }
       
   312     data.internalGc.copyArea(srcX, srcY, width, height, destX, destY, paint);
       
   313 }
       
   314 
       
   315 /**
       
   316  * Disposes of the operating system resources associated with the graphics
       
   317  * context. Applications must dispose of all the GCs which they allocate.
       
   318  * 
       
   319  * @exception SWTError
       
   320  *                <ul>
       
   321  *                <li>ERROR_THREAD_INVALID_ACCESS if not called from the thread
       
   322  *                that created the drawable</li>
       
   323  */
       
   324 public void dispose() {
       
   325     if (drawable != null && handle != 0) {
       
   326         if (data.buffered && (drawable instanceof Control)) {
       
   327             final Display display = Display.getDefault();
       
   328             display.syncExec(new Runnable() {
       
   329                 public void run() {
       
   330                     ((Control) drawable).redraw();
       
   331                     while (display.readAndDispatch())
       
   332                         ;
       
   333                 }
       
   334             });
       
   335         }
       
   336         drawable.internal_dispose_GC(data);
       
   337     }
       
   338 
       
   339     data.destroy();
       
   340 
       
   341     handle = SWT.NULL;
       
   342     customForeground = null;
       
   343     customBackground = null;
       
   344     drawable = null;
       
   345 }
       
   346 
       
   347 /**
       
   348  * Draws the outline of a circular or elliptical arc within the specified
       
   349  * rectangular area.
       
   350  * <p>
       
   351  * The resulting arc begins at <code>startAngle</code> and extends for <code>
       
   352  * arcAngle</code> degrees, using the current color. Angles are interpreted such
       
   353  * that 0 degrees is at the 3 o'clock position. A positive value indicates a
       
   354  * counter-clockwise rotation while a negative value indicates a clockwise
       
   355  * rotation.
       
   356  * </p>
       
   357  * <p>
       
   358  * The center of the arc is the center of the rectangle whose origin is (<code>x
       
   359  * </code>, <code>y</code>) and whose size is specified by the <code>width
       
   360  * </code> and <code>height</code> arguments.
       
   361  * </p>
       
   362  * <p>
       
   363  * The resulting arc covers an area <code>width + 1</code> pixels wide by <code>
       
   364  * height + 1</code> pixels tall.
       
   365  * </p>
       
   366  * 
       
   367  * @param x
       
   368  *            the x coordinate of the upper-left corner of the arc to be drawn
       
   369  * @param y
       
   370  *            the y coordinate of the upper-left corner of the arc to be drawn
       
   371  * @param width
       
   372  *            the width of the arc to be drawn
       
   373  * @param height
       
   374  *            the height of the arc to be drawn
       
   375  * @param startAngle
       
   376  *            the beginning angle
       
   377  * @param arcAngle
       
   378  *            the angular extent of the arc, relative to the start angle
       
   379  * 
       
   380  * @exception SWTException
       
   381  *                <ul>
       
   382  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
   383  *                </li>
       
   384  *                </ul>
       
   385  */
       
   386 public void drawArc(int x, int y, int width, int height, int startAngle,
       
   387         int arcAngle) {
       
   388     if (handle == 0) {
       
   389         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
   390     }
       
   391     if (width < 0) {
       
   392         x = x + width;
       
   393         width = -width;
       
   394     }
       
   395     if (height < 0) {
       
   396         y = y + height;
       
   397         height = -height;
       
   398     }
       
   399     if (width == 0 || height == 0 || arcAngle == 0) {
       
   400         return;
       
   401     }
       
   402     checkGC(FOREGROUND);
       
   403     data.internalGc.drawArc(x, y, width, height, startAngle, arcAngle);
       
   404 }
       
   405 
       
   406 /**
       
   407  * Draws a rectangle, based on the specified arguments, which has the appearance
       
   408  * of the platform's <em>focus rectangle</em> if the platform supports such a
       
   409  * notion, and otherwise draws a simple rectangle in the receiver's foreground
       
   410  * color.
       
   411  * 
       
   412  * @param x
       
   413  *            the x coordinate of the rectangle
       
   414  * @param y
       
   415  *            the y coordinate of the rectangle
       
   416  * @param width
       
   417  *            the width of the rectangle
       
   418  * @param height
       
   419  *            the height of the rectangle
       
   420  * 
       
   421  * @exception SWTException
       
   422  *                <ul>
       
   423  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
   424  *                </li>
       
   425  *                </ul>
       
   426  * 
       
   427  * @see #drawRectangle(int, int, int, int)
       
   428  */
       
   429 public void drawFocus(int x, int y, int width, int height) {
       
   430     if (handle == 0) {
       
   431         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
   432     }
       
   433     checkGC(FOREGROUND);
       
   434     data.internalGc.drawFocus(x, y, width, height);
       
   435 }
       
   436 
       
   437 /**
       
   438  * Draws the given image in the receiver at the specified coordinates.
       
   439  * 
       
   440  * @param image
       
   441  *            the image to draw
       
   442  * @param x
       
   443  *            the x coordinate of where to draw
       
   444  * @param y
       
   445  *            the y coordinate of where to draw
       
   446  * 
       
   447  * @exception IllegalArgumentException
       
   448  *                <ul>
       
   449  *                <li>ERROR_NULL_ARGUMENT - if the image is null</li>
       
   450  *                <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
       
   451  *                <li>ERROR_INVALID_ARGUMENT - if the given coordinates are
       
   452  *                outside the bounds of the image</li>
       
   453  * @exception SWTException
       
   454  *                <ul>
       
   455  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
   456  *                </li>
       
   457  *                </ul>
       
   458  * @exception SWTError
       
   459  *                <ul>
       
   460  *                <li>ERROR_NO_HANDLES - if no handles are available to perform
       
   461  *                the operation</li>
       
   462  *                </ul>
       
   463  */
       
   464 public void drawImage(Image image, int x, int y) {
       
   465     if (handle == 0) {
       
   466         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
   467     }
       
   468     if (image == null) {
       
   469         SWT.error(SWT.ERROR_NULL_ARGUMENT);
       
   470     }
       
   471     if (image.isDisposed()) {
       
   472         SWT.error(SWT.ERROR_INVALID_ARGUMENT);
       
   473     }
       
   474     // Reset all mirroring transformation and calculate the mirrored coordinates
       
   475     // manually.
       
   476     if ((data.style & SWT.MIRRORED) != 0) {
       
   477         data.internalGc.resetTransform();
       
   478         data.state = ~FOREGROUND;
       
   479         int clientWidth = OS.QPaintDevice_width(data.drawable);
       
   480         x = clientWidth - x - image.getBounds().width;
       
   481     }
       
   482     data.internalGc.drawImage(image.getImage(), x, y);
       
   483 }
       
   484 
       
   485 /**
       
   486  * Copies a rectangular area from the source image into a (potentially different
       
   487  * sized) rectangular area in the receiver. If the source and destination areas
       
   488  * are of differing sizes, then the source area will be stretched or shrunk to
       
   489  * fit the destination area as it is copied. The copy fails if any part of the
       
   490  * source rectangle lies outside the bounds of the source image, or if any of
       
   491  * the width or height arguments are negative.
       
   492  * 
       
   493  * @param image
       
   494  *            the source image
       
   495  * @param srcX
       
   496  *            the x coordinate in the source image to copy from
       
   497  * @param srcY
       
   498  *            the y coordinate in the source image to copy from
       
   499  * @param srcWidth
       
   500  *            the width in pixels to copy from the source
       
   501  * @param srcHeight
       
   502  *            the height in pixels to copy from the source
       
   503  * @param destX
       
   504  *            the x coordinate in the destination to copy to
       
   505  * @param destY
       
   506  *            the y coordinate in the destination to copy to
       
   507  * @param destWidth
       
   508  *            the width in pixels of the destination rectangle
       
   509  * @param destHeight
       
   510  *            the height in pixels of the destination rectangle
       
   511  * 
       
   512  * @exception IllegalArgumentException
       
   513  *                <ul>
       
   514  *                <li>ERROR_NULL_ARGUMENT - if the image is null</li>
       
   515  *                <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
       
   516  *                <li>ERROR_INVALID_ARGUMENT - if any of the width or height
       
   517  *                arguments are negative.
       
   518  *                <li>ERROR_INVALID_ARGUMENT - if the source rectangle is not
       
   519  *                contained within the bounds of the source image</li>
       
   520  *                </ul>
       
   521  * @exception SWTException
       
   522  *                <ul>
       
   523  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
   524  *                </li>
       
   525  *                </ul>
       
   526  * @exception SWTError
       
   527  *                <ul>
       
   528  *                <li>ERROR_NO_HANDLES - if no handles are available to perform
       
   529  *                the operation</li>
       
   530  *                </ul>
       
   531  */
       
   532 public void drawImage(Image image, int srcX, int srcY, int srcWidth,
       
   533         int srcHeight, int destX, int destY, int destWidth, int destHeight) {
       
   534     if (handle == 0) {
       
   535         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
   536     }
       
   537     if (srcWidth == 0 || srcHeight == 0 || destWidth == 0 || destHeight == 0) {
       
   538         return;
       
   539     }
       
   540     if (srcX < 0 || srcY < 0 || srcWidth < 0 || srcHeight < 0 || destWidth < 0
       
   541             || destHeight < 0) {
       
   542         SWT.error(SWT.ERROR_INVALID_ARGUMENT);
       
   543     }
       
   544     if (image == null) {
       
   545         SWT.error(SWT.ERROR_NULL_ARGUMENT);
       
   546     }
       
   547     if (image.isDisposed()) {
       
   548         SWT.error(SWT.ERROR_INVALID_ARGUMENT);
       
   549     }
       
   550     // Reset all mirroring transformation and calculate the mirrored coordinates
       
   551     // manually.
       
   552     if ((data.style & SWT.MIRRORED) != 0) {
       
   553         data.internalGc.resetTransform();
       
   554         data.state = ~FOREGROUND;
       
   555         int clientWidth = OS.QPaintDevice_width(data.drawable);
       
   556         srcX = image.getBounds().width - srcX - srcWidth;
       
   557         destX = clientWidth - destX - destWidth;
       
   558     }
       
   559     data.internalGc.drawImage(image.getImage(), destX, destY,
       
   560             destWidth, destHeight, srcX, srcY, srcWidth, srcHeight);
       
   561 }
       
   562 
       
   563 /**
       
   564  * Draws a line, using the foreground color, between the points (<code>x1</code>
       
   565  * , <code>y1</code>) and (<code>x2</code>, <code>y2</code>).
       
   566  * 
       
   567  * @param x1
       
   568  *            the first point's x coordinate
       
   569  * @param y1
       
   570  *            the first point's y coordinate
       
   571  * @param x2
       
   572  *            the second point's x coordinate
       
   573  * @param y2
       
   574  *            the second point's y coordinate
       
   575  * 
       
   576  * @exception SWTException
       
   577  *                <ul>
       
   578  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
   579  *                </li>
       
   580  *                </ul>
       
   581  */
       
   582 public void drawLine(int x1, int y1, int x2, int y2) {
       
   583     if (handle == 0) {
       
   584         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
   585     }
       
   586     checkGC(FOREGROUND);
       
   587     data.internalGc.drawLine(x1, y1, x2, y2);
       
   588 }
       
   589 
       
   590 /**
       
   591  * Draws the outline of an oval, using the foreground color, within the
       
   592  * specified rectangular area.
       
   593  * <p>
       
   594  * The result is a circle or ellipse that fits within the rectangle specified by
       
   595  * the <code>x</code>, <code>y</code>, <code>width</code>, and
       
   596  * <code>height</code> arguments.
       
   597  * </p>
       
   598  * <p>
       
   599  * The oval covers an area that is <code>width + 1</code> pixels wide and
       
   600  * <code>height + 1</code> pixels tall.
       
   601  * </p>
       
   602  * 
       
   603  * @param x
       
   604  *            the x coordinate of the upper left corner of the oval to be drawn
       
   605  * @param y
       
   606  *            the y coordinate of the upper left corner of the oval to be drawn
       
   607  * @param width
       
   608  *            the width of the oval to be drawn
       
   609  * @param height
       
   610  *            the height of the oval to be drawn
       
   611  * 
       
   612  * @exception SWTException
       
   613  *                <ul>
       
   614  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
   615  *                </li>
       
   616  *                </ul>
       
   617  */
       
   618 public void drawOval(int x, int y, int width, int height) {
       
   619     if (handle == 0) {
       
   620         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
   621     }
       
   622     if (width < 0) {
       
   623         x = x + width;
       
   624         width = -width;
       
   625     }
       
   626     if (height < 0) {
       
   627         y = y + height;
       
   628         height = -height;
       
   629     }
       
   630     checkGC(FOREGROUND);
       
   631     data.internalGc.drawEllipse(x, y, width, height);
       
   632 }
       
   633 
       
   634 /**
       
   635  * Draws a pixel, using the foreground color, at the specified point (
       
   636  * <code>x</code>, <code>y</code>).
       
   637  * <p>
       
   638  * Note that the receiver's line attributes do not affect this operation.
       
   639  * </p>
       
   640  * 
       
   641  * @param x
       
   642  *            the point's x coordinate
       
   643  * @param y
       
   644  *            the point's y coordinate
       
   645  * 
       
   646  * @exception SWTException
       
   647  *                <ul>
       
   648  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
   649  *                </li>
       
   650  *                </ul>
       
   651  * 
       
   652  * @since 3.0
       
   653  */
       
   654 public void drawPoint(int x, int y) {
       
   655     if (handle == 0) {
       
   656         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
   657     }
       
   658     checkGC(FOREGROUND);
       
   659     data.internalGc.drawPoint(x, y);
       
   660 }
       
   661 
       
   662 /**
       
   663  * Draws the closed polygon which is defined by the specified array of integer
       
   664  * coordinates, using the receiver's foreground color. The array contains
       
   665  * alternating x and y values which are considered to represent points which are
       
   666  * the vertices of the polygon. Lines are drawn between each consecutive pair,
       
   667  * and between the first pair and last pair in the array.
       
   668  * 
       
   669  * @param pointArray
       
   670  *            an array of alternating x and y values which are the vertices of
       
   671  *            the polygon
       
   672  * 
       
   673  * @exception IllegalArgumentException
       
   674  *                <ul>
       
   675  *                <li>ERROR_NULL_ARGUMENT if pointArray is null</li>
       
   676  *                </ul>
       
   677  * @exception SWTException
       
   678  *                <ul>
       
   679  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
   680  *                </li>
       
   681  *                </ul>
       
   682  */
       
   683 public void drawPolygon(int[] pointArray) {
       
   684     if (handle == 0) {
       
   685         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
   686     }
       
   687     if (pointArray == null) {
       
   688         SWT.error(SWT.ERROR_NULL_ARGUMENT);
       
   689     }
       
   690     checkGC(FOREGROUND);
       
   691     data.internalGc.drawPolygon(pointArray);
       
   692 }
       
   693 
       
   694 /**
       
   695  * Draws the polyline which is defined by the specified array of integer
       
   696  * coordinates, using the receiver's foreground color. The array contains
       
   697  * alternating x and y values which are considered to represent points which are
       
   698  * the corners of the polyline. Lines are drawn between each consecutive pair,
       
   699  * but not between the first pair and last pair in the array.
       
   700  * 
       
   701  * @param pointArray
       
   702  *            an array of alternating x and y values which are the corners of
       
   703  *            the polyline
       
   704  * 
       
   705  * @exception IllegalArgumentException
       
   706  *                <ul>
       
   707  *                <li>ERROR_NULL_ARGUMENT - if the point array is null</li>
       
   708  *                </ul>
       
   709  * @exception SWTException
       
   710  *                <ul>
       
   711  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
   712  *                </li>
       
   713  *                </ul>
       
   714  */
       
   715 public void drawPolyline(int[] pointArray) {
       
   716     if (handle == 0) {
       
   717         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
   718     }
       
   719     if (pointArray == null) {
       
   720         SWT.error(SWT.ERROR_NULL_ARGUMENT);
       
   721     }
       
   722     checkGC(FOREGROUND);
       
   723     data.internalGc.drawPolyline(pointArray);
       
   724 }
       
   725 
       
   726 /**
       
   727  * Draws the outline of the rectangle specified by the arguments, using the
       
   728  * receiver's foreground color. The left and right edges of the rectangle are at
       
   729  * <code>x</code> and <code>x + width</code>. The top and bottom edges are at
       
   730  * <code>y</code> and <code>y + height</code>.
       
   731  * 
       
   732  * @param x
       
   733  *            the x coordinate of the rectangle to be drawn
       
   734  * @param y
       
   735  *            the y coordinate of the rectangle to be drawn
       
   736  * @param width
       
   737  *            the width of the rectangle to be drawn
       
   738  * @param height
       
   739  *            the height of the rectangle to be drawn
       
   740  * 
       
   741  * @exception SWTException
       
   742  *                <ul>
       
   743  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
   744  *                </li>
       
   745  *                </ul>
       
   746  */
       
   747 public void drawRectangle(int x, int y, int width, int height) {
       
   748     if (handle == 0) {
       
   749         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
   750     }
       
   751     if (width < 0) {
       
   752         x = x + width;
       
   753         width = -width;
       
   754     }
       
   755     if (height < 0) {
       
   756         y = y + height;
       
   757         height = -height;
       
   758     }
       
   759     checkGC(FOREGROUND);
       
   760     data.internalGc.drawRect(x, y, width, height);
       
   761 }
       
   762 
       
   763 /**
       
   764  * Draws the outline of the specified rectangle, using the receiver's foreground
       
   765  * color. The left and right edges of the rectangle are at <code>rect.x</code>
       
   766  * and <code>rect.x + rect.width</code>. The top and bottom edges are at
       
   767  * <code>rect.y</code> and <code>rect.y + rect.height</code>.
       
   768  * 
       
   769  * @param rect
       
   770  *            the rectangle to draw
       
   771  * 
       
   772  * @exception IllegalArgumentException
       
   773  *                <ul>
       
   774  *                <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li>
       
   775  *                </ul>
       
   776  * @exception SWTException
       
   777  *                <ul>
       
   778  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
   779  *                </li>
       
   780  *                </ul>
       
   781  */
       
   782 public void drawRectangle(Rectangle rect) {
       
   783     if (rect == null) {
       
   784         SWT.error(SWT.ERROR_NULL_ARGUMENT);
       
   785     }
       
   786     drawRectangle(rect.x, rect.y, rect.width, rect.height);
       
   787 }
       
   788 
       
   789 /**
       
   790  * Draws the outline of the round-cornered rectangle specified by the arguments,
       
   791  * using the receiver's foreground color. The left and right edges of the
       
   792  * rectangle are at <code>x</code> and <code>x + width</code>. The top and
       
   793  * bottom edges are at <code>y</code> and <code>y + height</code>. The
       
   794  * <em>roundness</em> of the corners is specified by the <code>arcWidth</code>
       
   795  * and <code>arcHeight</code> arguments, which are respectively the width and
       
   796  * height of the ellipse used to draw the corners.
       
   797  * 
       
   798  * @param x
       
   799  *            the x coordinate of the rectangle to be drawn
       
   800  * @param y
       
   801  *            the y coordinate of the rectangle to be drawn
       
   802  * @param width
       
   803  *            the width of the rectangle to be drawn
       
   804  * @param height
       
   805  *            the height of the rectangle to be drawn
       
   806  * @param arcWidth
       
   807  *            the width of the arc
       
   808  * @param arcHeight
       
   809  *            the height of the arc
       
   810  * 
       
   811  * @exception SWTException
       
   812  *                <ul>
       
   813  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
   814  *                </li>
       
   815  *                </ul>
       
   816  */
       
   817 public void drawRoundRectangle(int x, int y, int width, int height,
       
   818         int arcWidth, int arcHeight) {
       
   819     if (handle == 0) {
       
   820         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
   821     }
       
   822     checkGC(FOREGROUND);
       
   823     data.internalGc.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
       
   824 }
       
   825 
       
   826 /**
       
   827  * Draws the given string, using the receiver's current font and foreground
       
   828  * color. No tab expansion or carriage return processing will be performed. The
       
   829  * background of the rectangular area where the string is being drawn will be
       
   830  * filled with the receiver's background color.
       
   831  * 
       
   832  * @param string
       
   833  *            the string to be drawn
       
   834  * @param x
       
   835  *            the x coordinate of the top left corner of the rectangular area
       
   836  *            where the string is to be drawn
       
   837  * @param y
       
   838  *            the y coordinate of the top left corner of the rectangular area
       
   839  *            where the string is to be drawn
       
   840  * 
       
   841  * @exception IllegalArgumentException
       
   842  *                <ul>
       
   843  *                <li>ERROR_NULL_ARGUMENT - if the string is null</li>
       
   844  *                </ul>
       
   845  * @exception SWTException
       
   846  *                <ul>
       
   847  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
   848  *                </li>
       
   849  *                </ul>
       
   850  */
       
   851 public void drawString(String string, int x, int y) {
       
   852     drawString(string, x, y, false);
       
   853 }
       
   854 
       
   855 /**
       
   856  * Draws the given string, using the receiver's current font and foreground
       
   857  * color. No tab expansion or carriage return processing will be performed. If
       
   858  * <code>isTransparent</code> is <code>true</code>, then the background of the
       
   859  * rectangular area where the string is being drawn will not be modified,
       
   860  * otherwise it will be filled with the receiver's background color.
       
   861  * 
       
   862  * @param string
       
   863  *            the string to be drawn
       
   864  * @param x
       
   865  *            the x coordinate of the top left corner of the rectangular area
       
   866  *            where the string is to be drawn
       
   867  * @param y
       
   868  *            the y coordinate of the top left corner of the rectangular area
       
   869  *            where the string is to be drawn
       
   870  * @param isTransparent
       
   871  *            if <code>true</code> the background will be transparent, otherwise
       
   872  *            it will be opaque
       
   873  * 
       
   874  * @exception IllegalArgumentException
       
   875  *                <ul>
       
   876  *                <li>ERROR_NULL_ARGUMENT - if the string is null</li>
       
   877  *                </ul>
       
   878  * @exception SWTException
       
   879  *                <ul>
       
   880  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
   881  *                </li>
       
   882  *                </ul>
       
   883  */
       
   884 public void drawString(String string, int x, int y, boolean isTransparent) {
       
   885     if (handle == 0) {
       
   886         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
   887     }
       
   888     if (string == null) {
       
   889         SWT.error(SWT.ERROR_NULL_ARGUMENT);
       
   890     }
       
   891     if (string.length() == 0) {
       
   892         return;
       
   893     }
       
   894     // Reset all mirroring transformation and calculate the mirrored coordinates
       
   895     // manually.
       
   896     if ((data.style & SWT.MIRRORED) != 0) {
       
   897         data.internalGc.resetTransform();
       
   898         data.state = ~FOREGROUND;
       
   899         int clientWidth = OS.QPaintDevice_width(data.drawable);
       
   900         int box[] = new int[4];
       
   901         data.internalGc
       
   902                 .getTextBoundingBox(
       
   903                         box,
       
   904                         string,
       
   905                         (GraphicsContext.ALIGNMENT_LEFT | GraphicsContext.ALIGNMENT_TOP),
       
   906                         GraphicsContext.TEXT_SINGLE_LINE);
       
   907         x = clientWidth - x - box[GraphicsContext.RECT_WIDTH];
       
   908     }
       
   909     data.internalGc.drawString(string, x, y, isTransparent);
       
   910 }
       
   911 
       
   912 /**
       
   913  * Draws the given string, using the receiver's current font and foreground
       
   914  * color. Tab expansion and carriage return processing are performed. The
       
   915  * background of the rectangular area where the text is being drawn will be
       
   916  * filled with the receiver's background color.
       
   917  * 
       
   918  * @param string
       
   919  *            the string to be drawn
       
   920  * @param x
       
   921  *            the x coordinate of the top left corner of the rectangular area
       
   922  *            where the text is to be drawn
       
   923  * @param y
       
   924  *            the y coordinate of the top left corner of the rectangular area
       
   925  *            where the text is to be drawn
       
   926  * 
       
   927  * @exception IllegalArgumentException
       
   928  *                <ul>
       
   929  *                <li>ERROR_NULL_ARGUMENT - if the string is null</li>
       
   930  *                </ul>
       
   931  * @exception SWTException
       
   932  *                <ul>
       
   933  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
   934  *                </li>
       
   935  *                </ul>
       
   936  */
       
   937 public void drawText(String string, int x, int y) {
       
   938     drawText(string, x, y, SWT.DRAW_DELIMITER | SWT.DRAW_TAB);
       
   939 }
       
   940 
       
   941 /**
       
   942  * Draws the given string, using the receiver's current font and foreground
       
   943  * color. Tab expansion, line delimiter and mnemonic processing are performed
       
   944  * according to the specified flags. If <code>flags</code> includes
       
   945  * <code>DRAW_TRANSPARENT</code>, then the background of the rectangular area
       
   946  * where the text is being drawn will not be modified, otherwise it will be
       
   947  * filled with the receiver's background color.
       
   948  * <p>
       
   949  * The parameter <code>flags</code> may be a combination of:
       
   950  * <dl>
       
   951  * <dt><b>DRAW_DELIMITER</b></dt>
       
   952  * <dd>draw multiple lines</dd>
       
   953  * <dt><b>DRAW_TAB</b></dt>
       
   954  * <dd>expand tabs</dd>
       
   955  * <dt><b>DRAW_MNEMONIC</b></dt>
       
   956  * <dd>underline the mnemonic character</dd>
       
   957  * <dt><b>DRAW_TRANSPARENT</b></dt>
       
   958  * <dd>transparent background</dd>
       
   959  * </dl>
       
   960  * </p>
       
   961  * 
       
   962  * @param string
       
   963  *            the string to be drawn
       
   964  * @param x
       
   965  *            the x coordinate of the top left corner of the rectangular area
       
   966  *            where the text is to be drawn
       
   967  * @param y
       
   968  *            the y coordinate of the top left corner of the rectangular area
       
   969  *            where the text is to be drawn
       
   970  * @param flags
       
   971  *            the flags specifying how to process the text
       
   972  * 
       
   973  * @exception IllegalArgumentException
       
   974  *                <ul>
       
   975  *                <li>ERROR_NULL_ARGUMENT - if the string is null</li>
       
   976  *                </ul>
       
   977  * @exception SWTException
       
   978  *                <ul>
       
   979  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
   980  *                </li>
       
   981  *                </ul>
       
   982  */
       
   983 public void drawText(String string, int x, int y, int flags) {
       
   984     if (handle == 0) {
       
   985         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
   986     }
       
   987     if (string == null) {
       
   988         SWT.error(SWT.ERROR_NULL_ARGUMENT);
       
   989     }
       
   990     if (string.length() == 0) {
       
   991         return;
       
   992     }
       
   993 
       
   994     int translatedFlags = 0;
       
   995     boolean isTransparent = false;
       
   996 
       
   997     if ((flags & SWT.DRAW_DELIMITER) == 0) {
       
   998         translatedFlags |= GraphicsContext.TEXT_SINGLE_LINE;
       
   999     }
       
  1000     if ((flags & SWT.DRAW_TAB) != 0) {
       
  1001         translatedFlags |= GraphicsContext.TEXT_EXPAND_TABS;
       
  1002     }
       
  1003     if ((flags & SWT.DRAW_MNEMONIC) != 0) {
       
  1004         translatedFlags |= GraphicsContext.TEXT_SHOW_MNEMONIC;
       
  1005     }
       
  1006     if ((flags & SWT.DRAW_TRANSPARENT) != 0) {
       
  1007         isTransparent = true;
       
  1008     }
       
  1009     // Reset all mirroring transformation and calculate the mirrored coordinates
       
  1010     // manually.
       
  1011     if ((data.style & SWT.MIRRORED) != 0) {
       
  1012         data.internalGc.resetTransform();
       
  1013         data.state = ~FOREGROUND;
       
  1014         int clientWidth = OS.QPaintDevice_width(data.drawable);
       
  1015         int box[] = new int[4];
       
  1016         data.internalGc
       
  1017                 .getTextBoundingBox(
       
  1018                         box,
       
  1019                         string,
       
  1020                         (GraphicsContext.ALIGNMENT_HCENTER | GraphicsContext.ALIGNMENT_LEFT),
       
  1021                         translatedFlags);
       
  1022         x = clientWidth - x - box[GraphicsContext.RECT_WIDTH];
       
  1023     }
       
  1024     data.internalGc
       
  1025             .drawString(
       
  1026                     string,
       
  1027                     x,
       
  1028                     y,
       
  1029                     0,
       
  1030                     0,
       
  1031                     (GraphicsContext.ALIGNMENT_HCENTER | GraphicsContext.ALIGNMENT_LEFT),
       
  1032                     translatedFlags, isTransparent);
       
  1033 }
       
  1034 
       
  1035 /**
       
  1036  * Compares the argument to the receiver, and returns true if they represent the
       
  1037  * <em>same</em> object using a class specific comparison.
       
  1038  * 
       
  1039  * @param object
       
  1040  *            the object to compare with this object
       
  1041  * @return <code>true</code> if the object is the same as this object and
       
  1042  *         <code>false</code> otherwise
       
  1043  * 
       
  1044  * @see #hashCode
       
  1045  */
       
  1046 public boolean equals(Object object) {
       
  1047     if (object == this) {
       
  1048         return true;
       
  1049     }
       
  1050     if (!(object instanceof GC)) {
       
  1051         return false;
       
  1052     }
       
  1053     return handle == ((GC) object).handle;
       
  1054 }
       
  1055 
       
  1056 /**
       
  1057  * Fills the interior of a circular or elliptical arc within the specified
       
  1058  * rectangular area, with the receiver's background color.
       
  1059  * <p>
       
  1060  * The resulting arc begins at <code>startAngle</code> and extends for
       
  1061  * <code>arcAngle</code> degrees, using the current color. Angles are
       
  1062  * interpreted such that 0 degrees is at the 3 o'clock position. A positive
       
  1063  * value indicates a counter-clockwise rotation while a negative value indicates
       
  1064  * a clockwise rotation.
       
  1065  * </p>
       
  1066  * <p>
       
  1067  * The center of the arc is the center of the rectangle whose origin is (
       
  1068  * <code>x</code>, <code>y</code>) and whose size is specified by the
       
  1069  * <code>width</code> and <code>height</code> arguments.
       
  1070  * </p>
       
  1071  * <p>
       
  1072  * The resulting arc covers an area <code>width + 1</code> pixels wide by
       
  1073  * <code>height + 1</code> pixels tall.
       
  1074  * </p>
       
  1075  * 
       
  1076  * @param x
       
  1077  *            the x coordinate of the upper-left corner of the arc to be filled
       
  1078  * @param y
       
  1079  *            the y coordinate of the upper-left corner of the arc to be filled
       
  1080  * @param width
       
  1081  *            the width of the arc to be filled
       
  1082  * @param height
       
  1083  *            the height of the arc to be filled
       
  1084  * @param startAngle
       
  1085  *            the beginning angle
       
  1086  * @param arcAngle
       
  1087  *            the angular extent of the arc, relative to the start angle
       
  1088  * 
       
  1089  * @exception SWTException
       
  1090  *                <ul>
       
  1091  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1092  *                </li>
       
  1093  *                </ul>
       
  1094  * 
       
  1095  * @see #drawArc
       
  1096  */
       
  1097 public void fillArc(int x, int y, int width, int height, int startAngle,
       
  1098         int arcAngle) {
       
  1099     if (handle == 0) {
       
  1100         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1101     }
       
  1102     if (width < 0) {
       
  1103         x = x + width;
       
  1104         width = -width;
       
  1105     }
       
  1106     if (height < 0) {
       
  1107         y = y + height;
       
  1108         height = -height;
       
  1109     }
       
  1110     if (width == 0 || height == 0 || arcAngle == 0) {
       
  1111         return;
       
  1112     }
       
  1113     checkGC(FOREGROUND);
       
  1114     data.internalGc.fillArc(x, y, width, height, startAngle, arcAngle);
       
  1115 }
       
  1116 
       
  1117 /**
       
  1118  * Fills the interior of the specified rectangle with a gradient sweeping from
       
  1119  * left to right or top to bottom progressing from the receiver's foreground
       
  1120  * color to its background color.
       
  1121  * 
       
  1122  * @param x
       
  1123  *            the x coordinate of the rectangle to be filled
       
  1124  * @param y
       
  1125  *            the y coordinate of the rectangle to be filled
       
  1126  * @param width
       
  1127  *            the width of the rectangle to be filled, may be negative (inverts
       
  1128  *            direction of gradient if horizontal)
       
  1129  * @param height
       
  1130  *            the height of the rectangle to be filled, may be negative (inverts
       
  1131  *            direction of gradient if vertical)
       
  1132  * @param vertical
       
  1133  *            if true sweeps from top to bottom, else sweeps from left to right
       
  1134  * 
       
  1135  * @exception SWTException
       
  1136  *                <ul>
       
  1137  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1138  *                </li>
       
  1139  *                </ul>
       
  1140  * 
       
  1141  * @see #drawRectangle(int, int, int, int)
       
  1142  */
       
  1143 public void fillGradientRectangle(int x, int y, int width, int height,
       
  1144         boolean vertical) {
       
  1145     if (handle == 0) {
       
  1146         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1147     }
       
  1148     if ((width == 0) || (height == 0)) {
       
  1149         return;
       
  1150     }
       
  1151 
       
  1152     boolean swapColors = false;
       
  1153     if (width < 0) {
       
  1154         if (!vertical) {
       
  1155             swapColors = true;
       
  1156         }
       
  1157         width = Math.abs(width);
       
  1158     }
       
  1159     if (height < 0) {
       
  1160         if (vertical) {
       
  1161             swapColors = true;
       
  1162         }
       
  1163         height = Math.abs(height);
       
  1164     }
       
  1165     checkGC(FOREGROUND);
       
  1166     data.internalGc.fillGradientRect(x, y, width, height, vertical, swapColors);
       
  1167 }
       
  1168 
       
  1169 /**
       
  1170  * Fills the interior of an oval, within the specified rectangular area, with
       
  1171  * the receiver's background color.
       
  1172  * 
       
  1173  * @param x
       
  1174  *            the x coordinate of the upper left corner of the oval to be filled
       
  1175  * @param y
       
  1176  *            the y coordinate of the upper left corner of the oval to be filled
       
  1177  * @param width
       
  1178  *            the width of the oval to be filled
       
  1179  * @param height
       
  1180  *            the height of the oval to be filled
       
  1181  * 
       
  1182  * @exception SWTException
       
  1183  *                <ul>
       
  1184  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1185  *                </li>
       
  1186  *                </ul>
       
  1187  * 
       
  1188  * @see #drawOval
       
  1189  */
       
  1190 public void fillOval(int x, int y, int width, int height) {
       
  1191     if (handle == 0) {
       
  1192         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1193     }
       
  1194     if (width < 0) {
       
  1195         x = x + width;
       
  1196         width = -width;
       
  1197     }
       
  1198     if (height < 0) {
       
  1199         y = y + height;
       
  1200         height = -height;
       
  1201     }
       
  1202     checkGC(FOREGROUND);
       
  1203     data.internalGc.fillEllipse(x, y, width, height);
       
  1204 }
       
  1205 
       
  1206 /**
       
  1207  * Fills the interior of the closed polygon which is defined by the specified
       
  1208  * array of integer coordinates, using the receiver's background color. The
       
  1209  * array contains alternating x and y values which are considered to represent
       
  1210  * points which are the vertices of the polygon. Lines are drawn between each
       
  1211  * consecutive pair, and between the first pair and last pair in the array.
       
  1212  * 
       
  1213  * @param pointArray
       
  1214  *            an array of alternating x and y values which are the vertices of
       
  1215  *            the polygon
       
  1216  * 
       
  1217  * @exception IllegalArgumentException
       
  1218  *                <ul>
       
  1219  *                <li>ERROR_NULL_ARGUMENT if pointArray is null</li>
       
  1220  *                </ul>
       
  1221  * @exception SWTException
       
  1222  *                <ul>
       
  1223  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1224  *                </li>
       
  1225  *                </ul>
       
  1226  * 
       
  1227  * @see #drawPolygon
       
  1228  */
       
  1229 public void fillPolygon(int[] pointArray) {
       
  1230     if (handle == 0) {
       
  1231         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1232     }
       
  1233     if (pointArray == null) {
       
  1234         SWT.error(SWT.ERROR_NULL_ARGUMENT);
       
  1235     }
       
  1236     checkGC(FOREGROUND);
       
  1237     data.internalGc.fillPolygon(pointArray);
       
  1238 }
       
  1239 
       
  1240 /**
       
  1241  * Fills the interior of the rectangle specified by the arguments, using the
       
  1242  * receiver's background color.
       
  1243  * 
       
  1244  * @param x
       
  1245  *            the x coordinate of the rectangle to be filled
       
  1246  * @param y
       
  1247  *            the y coordinate of the rectangle to be filled
       
  1248  * @param width
       
  1249  *            the width of the rectangle to be filled
       
  1250  * @param height
       
  1251  *            the height of the rectangle to be filled
       
  1252  * 
       
  1253  * @exception SWTException
       
  1254  *                <ul>
       
  1255  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1256  *                </li>
       
  1257  *                </ul>
       
  1258  * 
       
  1259  * @see #drawRectangle(int, int, int, int)
       
  1260  */
       
  1261 public void fillRectangle(int x, int y, int width, int height) {
       
  1262     if (handle == 0) {
       
  1263         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1264     }
       
  1265     if (width < 0) {
       
  1266         x = x + width;
       
  1267         width = -width;
       
  1268     }
       
  1269     if (height < 0) {
       
  1270         y = y + height;
       
  1271         height = -height;
       
  1272     }
       
  1273     checkGC(FOREGROUND);
       
  1274     data.internalGc.fillRect(x, y, width, height);
       
  1275 }
       
  1276 
       
  1277 /**
       
  1278  * Fills the interior of the specified rectangle, using the receiver's
       
  1279  * background color.
       
  1280  * 
       
  1281  * @param rect
       
  1282  *            the rectangle to be filled
       
  1283  * 
       
  1284  * @exception IllegalArgumentException
       
  1285  *                <ul>
       
  1286  *                <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li>
       
  1287  *                </ul>
       
  1288  * @exception SWTException
       
  1289  *                <ul>
       
  1290  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1291  *                </li>
       
  1292  *                </ul>
       
  1293  * 
       
  1294  * @see #drawRectangle(int, int, int, int)
       
  1295  */
       
  1296 public void fillRectangle(Rectangle rect) {
       
  1297     if (handle == 0) {
       
  1298         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1299     }
       
  1300     if (rect == null) {
       
  1301         SWT.error(SWT.ERROR_NULL_ARGUMENT);
       
  1302     }
       
  1303     fillRectangle(rect.x, rect.y, rect.width, rect.height);
       
  1304 }
       
  1305 
       
  1306 /**
       
  1307  * Fills the interior of the round-cornered rectangle specified by the
       
  1308  * arguments, using the receiver's background color.
       
  1309  * 
       
  1310  * @param x
       
  1311  *            the x coordinate of the rectangle to be filled
       
  1312  * @param y
       
  1313  *            the y coordinate of the rectangle to be filled
       
  1314  * @param width
       
  1315  *            the width of the rectangle to be filled
       
  1316  * @param height
       
  1317  *            the height of the rectangle to be filled
       
  1318  * @param arcWidth
       
  1319  *            the width of the arc
       
  1320  * @param arcHeight
       
  1321  *            the height of the arc
       
  1322  * 
       
  1323  * @exception SWTException
       
  1324  *                <ul>
       
  1325  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1326  *                </li>
       
  1327  *                </ul>
       
  1328  * 
       
  1329  * @see #drawRoundRectangle
       
  1330  */
       
  1331 public void fillRoundRectangle(int x, int y, int width, int height,
       
  1332         int arcWidth, int arcHeight) {
       
  1333     if (handle == 0) {
       
  1334         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1335     }
       
  1336     checkGC(FOREGROUND);
       
  1337     data.internalGc.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
       
  1338 }
       
  1339 
       
  1340 /**
       
  1341  * Returns the <em>advance width</em> of the specified character in the font
       
  1342  * which is currently selected into the receiver.
       
  1343  * <p>
       
  1344  * The advance width is defined as the horizontal distance the cursor should
       
  1345  * move after printing the character in the selected font.
       
  1346  * </p>
       
  1347  * 
       
  1348  * @param ch
       
  1349  *            the character to measure
       
  1350  * @return the distance in the x direction to move past the character before
       
  1351  *         painting the next
       
  1352  * 
       
  1353  * @exception SWTException
       
  1354  *                <ul>
       
  1355  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1356  *                </li>
       
  1357  *                </ul>
       
  1358  */
       
  1359 public int getAdvanceWidth(char ch) {
       
  1360     if (handle == 0) {
       
  1361         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1362     }
       
  1363     return data.internalGc.getAdvancedCharacterWidth(ch);
       
  1364 }
       
  1365 
       
  1366 /**
       
  1367  * Returns the receiver's alpha value. Default alpha value is 0xFF, fully opaque
       
  1368  * 
       
  1369  * 
       
  1370  * @return the alpha value
       
  1371  * 
       
  1372  * @exception SWTException
       
  1373  *                <ul>
       
  1374  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1375  *                </li>
       
  1376  *                </ul>
       
  1377  */
       
  1378 public int getAlpha() {
       
  1379     if (handle == 0) {
       
  1380         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1381     }
       
  1382     return data.alpha;
       
  1383 }
       
  1384 
       
  1385 /**
       
  1386  * Returns the background color.
       
  1387  * 
       
  1388  * @return the receiver's background color
       
  1389  * 
       
  1390  * @exception SWTException
       
  1391  *                <ul>
       
  1392  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1393  *                </li>
       
  1394  *                </ul>
       
  1395  */
       
  1396 public Color getBackground() {
       
  1397     if (handle == 0) {
       
  1398         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1399     }
       
  1400     return customBackground != null ? customBackground : data.background;
       
  1401 }
       
  1402 
       
  1403 /**
       
  1404  * Returns the width of the specified character in the font selected into the
       
  1405  * receiver.
       
  1406  * <p>
       
  1407  * The width is defined as the space taken up by the actual character, not
       
  1408  * including the leading and tailing whitespace or overhang.
       
  1409  * </p>
       
  1410  * 
       
  1411  * @param ch
       
  1412  *            the character to measure
       
  1413  * @return the width of the character
       
  1414  * 
       
  1415  * @exception SWTException
       
  1416  *                <ul>
       
  1417  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1418  *                </li>
       
  1419  *                </ul>
       
  1420  */
       
  1421 public int getCharWidth(char ch) {
       
  1422     if (handle == 0) {
       
  1423         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1424     }
       
  1425     return data.internalGc.getCharacterWidth(ch);
       
  1426 }
       
  1427 
       
  1428 /**
       
  1429  * Returns the bounding rectangle of the receiver's clipping region. If no
       
  1430  * clipping region is set, the return value will be a rectangle which covers the
       
  1431  * entire bounds of the object the receiver is drawing on.
       
  1432  * 
       
  1433  * @return the bounding rectangle of the clipping region
       
  1434  * 
       
  1435  * @exception SWTException
       
  1436  *                <ul>
       
  1437  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1438  *                </li>
       
  1439  *                </ul>
       
  1440  */
       
  1441 public Rectangle getClipping() {
       
  1442     if (handle == 0) {
       
  1443         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1444     }
       
  1445     checkGC(FOREGROUND);
       
  1446     if (data.clippingRect == null) {
       
  1447         int[] clip = new int[4];
       
  1448         data.internalGc.getClip(clip);
       
  1449         data.clippingRect = new Rectangle(clip[GraphicsContext.RECT_X],
       
  1450                 clip[GraphicsContext.RECT_Y], clip[GraphicsContext.RECT_WIDTH],
       
  1451                 clip[GraphicsContext.RECT_HEIGHT]);
       
  1452     }
       
  1453     return new Rectangle(data.clippingRect.x, data.clippingRect.y,
       
  1454             data.clippingRect.width, data.clippingRect.height);
       
  1455 }
       
  1456 
       
  1457 /**
       
  1458  * Returns the font currently being used by the receiver to draw and measure
       
  1459  * text.
       
  1460  * 
       
  1461  * @return the receiver's font
       
  1462  * 
       
  1463  * @exception SWTException
       
  1464  *                <ul>
       
  1465  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1466  *                </li>
       
  1467  *                </ul>
       
  1468  */
       
  1469 public Font getFont() {
       
  1470     if (handle == 0) {
       
  1471         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1472     }
       
  1473     return data.font;
       
  1474 }
       
  1475 
       
  1476 /**
       
  1477  * Returns a FontMetrics which contains information about the font currently
       
  1478  * being used by the receiver to draw and measure text. Note that if the font is
       
  1479  * changed later, the font metrics object is not updated accordingly.
       
  1480  * 
       
  1481  * @return font metrics for the receiver's font
       
  1482  * 
       
  1483  * @exception SWTException
       
  1484  *                <ul>
       
  1485  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1486  *                </li>
       
  1487  *                </ul>
       
  1488  */
       
  1489 public FontMetrics getFontMetrics() {
       
  1490     if (handle == 0) {
       
  1491         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1492     }
       
  1493 
       
  1494     // Read the FontMetrics data from the native
       
  1495     int fmData[] = new int[FM_DATA_COUNT];
       
  1496     data.internalGc.getFontMetricsData(fmData, 0, false);
       
  1497     // Create and fill up FonMetrics object.
       
  1498     FontMetrics fm = new FontMetrics();
       
  1499     fm.ascent = fmData[FM_ASCENT];
       
  1500     fm.averageCharWidth = fmData[FM_AVERAGE_CHAR_WIDTH];
       
  1501     fm.descent = fmData[FM_DESCENT];
       
  1502     fm.height = fmData[FM_HEIGHT];
       
  1503     fm.leading = fmData[FM_LEADING];
       
  1504     return fm;
       
  1505 }
       
  1506 
       
  1507 /**
       
  1508  * Returns the receiver's foreground color.
       
  1509  * 
       
  1510  * @return the color used for drawing foreground things
       
  1511  * 
       
  1512  * @exception SWTException
       
  1513  *                <ul>
       
  1514  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1515  *                </li>
       
  1516  *                </ul>
       
  1517  */
       
  1518 public Color getForeground() {
       
  1519     if (isDisposed()) {
       
  1520         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1521     }
       
  1522     return customForeground != null ? customForeground : data.foreground;
       
  1523 }
       
  1524 
       
  1525 /**
       
  1526  * Returns the GCData.
       
  1527  * <p>
       
  1528  * <b>IMPORTANT:</b> This method is <em>not</em> part of the public API for
       
  1529  * <code>GC</code>. It is marked public only so that it can be shared within the
       
  1530  * packages provided by SWT. It is not available on all platforms, and should
       
  1531  * never be called from application code.
       
  1532  * </p>
       
  1533  * 
       
  1534  * @return the receiver's GCData
       
  1535  * 
       
  1536  * @exception SWTException
       
  1537  *                <ul>
       
  1538  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1539  *                </li>
       
  1540  *                </ul>
       
  1541  * 
       
  1542  * @see GCData
       
  1543  * 
       
  1544  * @since 3.2
       
  1545  */
       
  1546 public GCData getGCData() {
       
  1547     if (handle == 0) {
       
  1548         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1549     }
       
  1550     return data;
       
  1551 }
       
  1552 
       
  1553 /**
       
  1554  * Returns the receiver's line style, which will be one of the constants
       
  1555  * <code>SWT.LINE_SOLID</code>, <code>SWT.LINE_DASH</code>,
       
  1556  * <code>SWT.LINE_DOT</code>, <code>SWT.LINE_DASHDOT</code> or
       
  1557  * <code>SWT.LINE_DASHDOTDOT</code>.
       
  1558  * 
       
  1559  * @return the style used for drawing lines
       
  1560  * 
       
  1561  * @exception SWTException
       
  1562  *                <ul>
       
  1563  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1564  *                </li>
       
  1565  *                </ul>
       
  1566  */
       
  1567 public int getLineStyle() {
       
  1568     if (handle == 0) {
       
  1569         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1570     }
       
  1571     if (data.lineStyle == GCData.NOT_DEFINED) {
       
  1572         data.lineStyle = GCData.translateStrokeStyle(data.internalGc
       
  1573                 .getStrokeStyle(), false);
       
  1574     }
       
  1575     return data.lineStyle;
       
  1576 }
       
  1577 
       
  1578 /**
       
  1579  * Returns the width that will be used when drawing lines for all of the figure
       
  1580  * drawing operations (that is, <code>drawLine</code>,
       
  1581  * <code>drawRectangle</code>, <code>drawPolyline</code>, and so forth.
       
  1582  * 
       
  1583  * @return the receiver's line width
       
  1584  * 
       
  1585  * @exception SWTException
       
  1586  *                <ul>
       
  1587  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1588  *                </li>
       
  1589  *                </ul>
       
  1590  */
       
  1591 public int getLineWidth() {
       
  1592     if (handle == 0) {
       
  1593         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1594     }
       
  1595     if (data.lineWidth == GCData.NOT_DEFINED) {
       
  1596         data.lineWidth = data.internalGc.getStrokeWidth();
       
  1597     }
       
  1598     return data.lineWidth;
       
  1599 }
       
  1600 
       
  1601 /**
       
  1602  * Returns the receiver's style information.
       
  1603  * <p>
       
  1604  * Note that the value which is returned by this method <em>may
       
  1605  * not match</em> the value which was provided to the constructor when the
       
  1606  * receiver was created. This can occur when the underlying operating system
       
  1607  * does not support a particular combination of requested styles.
       
  1608  * </p>
       
  1609  * 
       
  1610  * @return the style bits. Possible values are:
       
  1611  *         <ul>
       
  1612  *         <li>LEFT_TO_RIGHT</li>
       
  1613  *         <li>RIGHT_TO_LEFT</li>
       
  1614  *         </ul>
       
  1615  * @exception SWTException
       
  1616  *                <ul>
       
  1617  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1618  *                </li>
       
  1619  *                </ul>
       
  1620  * 
       
  1621  * @since 2.1.2
       
  1622  */
       
  1623 public int getStyle() {
       
  1624     if (handle == 0) {
       
  1625         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1626     }
       
  1627     return data.style;
       
  1628 }
       
  1629 
       
  1630 /**
       
  1631  * Returns <code>true</code> if this GC is drawing in the mode where the
       
  1632  * resulting color in the destination is the <em>exclusive or</em> of the color
       
  1633  * values in the source and the destination, and <code>false</code> if it is
       
  1634  * drawing in the mode where the destination color is being replaced with the
       
  1635  * source color value.
       
  1636  * 
       
  1637  * @return <code>true</code> true if the receiver is in XOR mode, and false
       
  1638  *         otherwise
       
  1639  * 
       
  1640  * @exception SWTException
       
  1641  *                <ul>
       
  1642  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1643  *                </li>
       
  1644  *                </ul>
       
  1645  */
       
  1646 public boolean getXORMode() {
       
  1647     if (handle == 0) {
       
  1648         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1649     }
       
  1650     if (data.xorMode == GCData.NOT_DEFINED) {
       
  1651         data.xorMode = (data.internalGc.getBlendingMode() == GraphicsContext.BLENDING_MODE_XOR ? GCData.XOR_MODE_ON
       
  1652                 : GCData.XOR_MODE_OFF);
       
  1653     }
       
  1654     return (data.xorMode == GCData.XOR_MODE_ON);
       
  1655 }
       
  1656 
       
  1657 /**
       
  1658  * Returns an integer hash code for the receiver. Any two objects that return
       
  1659  * <code>true</code> when passed to <code>equals</code> must return the same
       
  1660  * value for this method.
       
  1661  * 
       
  1662  * @return the receiver's hash
       
  1663  * 
       
  1664  * @exception SWTException
       
  1665  *                <ul>
       
  1666  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1667  *                </li>
       
  1668  *                </ul>
       
  1669  * 
       
  1670  * @see #equals
       
  1671  */
       
  1672 public int hashCode() {
       
  1673     return handle;
       
  1674 }
       
  1675 
       
  1676 void init(Drawable drawable, GCData data, int /* long */gcHandle) {
       
  1677     this.drawable = drawable;
       
  1678     this.data = data;
       
  1679     this.handle = gcHandle;
       
  1680     if (data.foreground == null) {
       
  1681         data.foreground = data.device.getSystemColor(SWT.COLOR_BLACK);
       
  1682     }
       
  1683     if (data.background == null) {
       
  1684         data.background = data.device.getSystemColor(SWT.COLOR_WHITE);
       
  1685     }
       
  1686     data.internalGc.setForegroundColor(data.foreground.getRed(),
       
  1687             data.foreground.getGreen(), data.foreground.getBlue());
       
  1688     data.internalGc.setBackgroundColor(data.background.getRed(),
       
  1689             data.background.getGreen(), data.background.getBlue());
       
  1690     this.drawable = drawable;
       
  1691     this.data = data;
       
  1692     handle = gcHandle;
       
  1693 }
       
  1694 
       
  1695 /**
       
  1696  * Returns <code>true</code> if the receiver has a clipping region set into it,
       
  1697  * and <code>false</code> otherwise. If this method returns false, the receiver
       
  1698  * will draw on all available space in the destination. If it returns true, it
       
  1699  * will draw only in the area that is covered by the region that can be accessed
       
  1700  * with <code>getClipping(region)</code>.
       
  1701  * 
       
  1702  * @return <code>true</code> if the GC has a clipping region, and
       
  1703  *         <code>false</code> otherwise
       
  1704  * 
       
  1705  * @exception SWTException
       
  1706  *                <ul>
       
  1707  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1708  *                </li>
       
  1709  *                </ul>
       
  1710  */
       
  1711 public boolean isClipped() {
       
  1712     if (handle == 0) {
       
  1713         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1714     }
       
  1715     return data.internalGc.hasClipping();
       
  1716 }
       
  1717 
       
  1718 /**
       
  1719  * Returns <code>true</code> if the GC has been disposed, and <code>false</code>
       
  1720  * otherwise.
       
  1721  * <p>
       
  1722  * This method gets the dispose state for the GC. When a GC has been disposed,
       
  1723  * it is an error to invoke any other method using the GC.
       
  1724  * 
       
  1725  * @return <code>true</code> when the GC is disposed and <code>false</code>
       
  1726  *         otherwise
       
  1727  */
       
  1728 public boolean isDisposed() {
       
  1729     return handle == 0;
       
  1730 }
       
  1731 
       
  1732 /**
       
  1733  * Sets the receiver's alpha value.
       
  1734  * <p>
       
  1735  * This operation requires the operating system's advanced graphics subsystem
       
  1736  * which may not be available on some platforms.
       
  1737  * </p>
       
  1738  * 
       
  1739  * @param alpha
       
  1740  *            the alpha value
       
  1741  * 
       
  1742  * @exception SWTException
       
  1743  *                <ul>
       
  1744  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1745  *                </li>
       
  1746  *                <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not
       
  1747  *                available</li>
       
  1748  *                </ul>
       
  1749  * 
       
  1750  * @see #getAdvanced
       
  1751  * @see #setAdvanced
       
  1752  * 
       
  1753  * @since 3.1
       
  1754  */
       
  1755 public void setAlpha(int alpha) {
       
  1756     if (handle == 0) {
       
  1757         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1758     }
       
  1759     data.alpha = alpha & 0xff;
       
  1760     data.internalGc.setForegroundAlpha(data.alpha);
       
  1761     data.internalGc.setBackgroundAlpha(data.alpha);
       
  1762 }
       
  1763 
       
  1764 /**
       
  1765  * Sets the background color. The background color is used for fill operations
       
  1766  * and as the background color when text is drawn.
       
  1767  * 
       
  1768  * @param color
       
  1769  *            the new background color for the receiver
       
  1770  * 
       
  1771  * @exception IllegalArgumentException
       
  1772  *                <ul>
       
  1773  *                <li>ERROR_NULL_ARGUMENT - if the color is null</li>
       
  1774  *                <li>ERROR_INVALID_ARGUMENT - if the color has been disposed</li>
       
  1775  *                </ul>
       
  1776  * @exception SWTException
       
  1777  *                <ul>
       
  1778  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1779  *                </li>
       
  1780  *                </ul>
       
  1781  */
       
  1782 public void setBackground(Color color) {
       
  1783     if (handle == 0) {
       
  1784         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1785     }
       
  1786     if (color == null) {
       
  1787         SWT.error(SWT.ERROR_NULL_ARGUMENT);
       
  1788     }
       
  1789     if (color.isDisposed()) {
       
  1790         SWT.error(SWT.ERROR_INVALID_ARGUMENT);
       
  1791     }
       
  1792     this.customBackground = color;
       
  1793     data.internalGc.setBackgroundColor(color.getRed(), color.getGreen(), color
       
  1794             .getBlue());
       
  1795 }
       
  1796 
       
  1797 /**
       
  1798  * Sets the area of the receiver which can be changed by drawing operations to
       
  1799  * the rectangular area specified by the arguments.
       
  1800  * 
       
  1801  * @param x
       
  1802  *            the x coordinate of the clipping rectangle
       
  1803  * @param y
       
  1804  *            the y coordinate of the clipping rectangle
       
  1805  * @param width
       
  1806  *            the width of the clipping rectangle
       
  1807  * @param height
       
  1808  *            the height of the clipping rectangle
       
  1809  * 
       
  1810  * @exception SWTException
       
  1811  *                <ul>
       
  1812  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1813  *                </li>
       
  1814  *                </ul>
       
  1815  */
       
  1816 public void setClipping(int x, int y, int width, int height) {
       
  1817     if (handle == 0) {
       
  1818         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1819     }
       
  1820     if (width < 0) {
       
  1821         x = x + width;
       
  1822         width = -width;
       
  1823     }
       
  1824     if (height < 0) {
       
  1825         y = y + height;
       
  1826         height = -height;
       
  1827     }
       
  1828     // Reset all mirroring transformation and calculate the mirrored coordinates
       
  1829     // manually.
       
  1830     if ((data.style & SWT.MIRRORED) != 0) {
       
  1831         data.internalGc.resetTransform();
       
  1832         data.state = ~FOREGROUND;
       
  1833         int clientWidth = OS.QPaintDevice_width(data.drawable);
       
  1834         x = clientWidth - x - (width + 1);
       
  1835     }
       
  1836     data.clippingRect = new Rectangle(x, y, width, height);
       
  1837     data.internalGc.setClip(x, y, width + 1, height, false);
       
  1838 }
       
  1839 
       
  1840 /**
       
  1841  * Sets the area of the receiver which can be changed by drawing operations to
       
  1842  * the rectangular area specified by the argument. Specifying <code>null</code>
       
  1843  * for the rectangle reverts the receiver's clipping area to its original value.
       
  1844  * 
       
  1845  * @param rect
       
  1846  *            the clipping rectangle or <code>null</code>
       
  1847  * 
       
  1848  * @exception SWTException
       
  1849  *                <ul>
       
  1850  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1851  *                </li>
       
  1852  *                </ul>
       
  1853  */
       
  1854 public void setClipping(Rectangle rect) {
       
  1855     if (handle == 0)
       
  1856         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1857     if (rect != null) {
       
  1858         setClipping(rect.x, rect.y, rect.width, rect.height);
       
  1859     } else {
       
  1860         data.internalGc.cancelClipping();
       
  1861     }
       
  1862 }
       
  1863 
       
  1864 /**
       
  1865  * Sets the font which will be used by the receiver to draw and measure text to
       
  1866  * the argument. If the argument is null, then a default font appropriate for
       
  1867  * the platform will be used instead.
       
  1868  * 
       
  1869  * @param font
       
  1870  *            the new font for the receiver, or null to indicate a default font
       
  1871  * 
       
  1872  * @exception IllegalArgumentException
       
  1873  *                <ul>
       
  1874  *                <li>ERROR_INVALID_ARGUMENT - if the font has been disposed</li>
       
  1875  *                </ul>
       
  1876  * @exception SWTException
       
  1877  *                <ul>
       
  1878  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1879  *                </li>
       
  1880  *                </ul>
       
  1881  */
       
  1882 public void setFont(Font font) {
       
  1883     if (handle == 0) {
       
  1884         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1885     }
       
  1886     if (font != null && font.isDisposed()) {
       
  1887         SWT.error(SWT.ERROR_INVALID_ARGUMENT);
       
  1888     }
       
  1889     data.font = font != null ? font : Font.qt_new(data.device, OS.SwtFontCache_cache(OS.QApplication_swt_font_new()));
       
  1890     data.internalGc.setFont(data.font.handle);
       
  1891 }
       
  1892 
       
  1893 /**
       
  1894  * Sets the foreground color. The foreground color is used for drawing
       
  1895  * operations including when text is drawn.
       
  1896  * 
       
  1897  * @param color
       
  1898  *            the new foreground color for the receiver
       
  1899  * 
       
  1900  * @exception IllegalArgumentException
       
  1901  *                <ul>
       
  1902  *                <li>ERROR_NULL_ARGUMENT - if the color is null</li>
       
  1903  *                <li>ERROR_INVALID_ARGUMENT - if the color has been disposed</li>
       
  1904  *                </ul>
       
  1905  * @exception SWTException
       
  1906  *                <ul>
       
  1907  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1908  *                </li>
       
  1909  *                </ul>
       
  1910  */
       
  1911 public void setForeground(Color color) {
       
  1912     if (handle == 0) {
       
  1913         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1914     }
       
  1915     if (color == null) {
       
  1916         SWT.error(SWT.ERROR_NULL_ARGUMENT);
       
  1917     }
       
  1918     if (color.isDisposed()) {
       
  1919         SWT.error(SWT.ERROR_INVALID_ARGUMENT);
       
  1920     }
       
  1921     customForeground = color;
       
  1922     data.internalGc.setForegroundColor(color.getRed(), color.getGreen(), color
       
  1923             .getBlue());
       
  1924 }
       
  1925 
       
  1926 /**
       
  1927  * Sets the receiver's line style to the argument, which must be one of the
       
  1928  * constants <code>SWT.LINE_SOLID</code>, <code>SWT.LINE_DASH</code>,
       
  1929  * <code>SWT.LINE_DOT</code>, <code>SWT.LINE_DASHDOT</code> or
       
  1930  * <code>SWT.LINE_DASHDOTDOT</code>.
       
  1931  * 
       
  1932  * @param lineStyle
       
  1933  *            the style to be used for drawing lines
       
  1934  * 
       
  1935  * @exception IllegalArgumentException
       
  1936  *                <ul>
       
  1937  *                <li>ERROR_INVALID_ARGUMENT - if the style is not valid</li>
       
  1938  *                </ul>
       
  1939  * @exception SWTException
       
  1940  *                <ul>
       
  1941  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1942  *                </li>
       
  1943  *                </ul>
       
  1944  */
       
  1945 public void setLineStyle(int lineStyle) {
       
  1946     if (handle == 0) {
       
  1947         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1948     }
       
  1949     if (data.lineStyle == lineStyle) {
       
  1950         return;
       
  1951     }
       
  1952     data.internalGc
       
  1953             .setStrokeStyle(GCData.translateStrokeStyle(lineStyle, true));
       
  1954     data.lineStyle = lineStyle;
       
  1955 }
       
  1956 
       
  1957 /**
       
  1958  * Sets the width that will be used when drawing lines for all of the figure
       
  1959  * drawing operations (that is, <code>drawLine</code>,
       
  1960  * <code>drawRectangle</code>, <code>drawPolyline</code>, and so forth.
       
  1961  * <p>
       
  1962  * Note that line width of zero is used as a hint to indicate that the fastest
       
  1963  * possible line drawing algorithms should be used. This means that the output
       
  1964  * may be different from line width one.
       
  1965  * </p>
       
  1966  * 
       
  1967  * @param lineWidth
       
  1968  *            the width of a line
       
  1969  * 
       
  1970  * @exception SWTException
       
  1971  *                <ul>
       
  1972  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  1973  *                </li>
       
  1974  *                </ul>
       
  1975  */
       
  1976 public void setLineWidth(int lineWidth) {
       
  1977     if (handle == 0) {
       
  1978         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  1979     }
       
  1980     if (data.lineWidth == lineWidth) {
       
  1981         return;
       
  1982     }
       
  1983     data.lineWidth = lineWidth;
       
  1984     data.internalGc.setStrokeWidth(lineWidth);
       
  1985 }
       
  1986 
       
  1987 /**
       
  1988  * If the argument is <code>true</code>, puts the receiver in a drawing mode
       
  1989  * where the resulting color in the destination is the <em>exclusive or</em> of
       
  1990  * the color values in the source and the destination, and if the argument is
       
  1991  * <code>false</code>, puts the receiver in a drawing mode where the destination
       
  1992  * color is replaced with the source color value.
       
  1993  * <p>
       
  1994  * Note that this mode in fundamentally unsupportable on certain platforms,
       
  1995  * notably Carbon (Mac OS X). Clients that want their code to run on all
       
  1996  * platforms need to avoid this method.
       
  1997  * </p>
       
  1998  * 
       
  1999  * @param xor
       
  2000  *            if <code>true</code>, then <em>xor</em> mode is used, otherwise
       
  2001  *            <em>source copy</em> mode is used
       
  2002  * 
       
  2003  * @exception SWTException
       
  2004  *                <ul>
       
  2005  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  2006  *                </li>
       
  2007  *                </ul>
       
  2008  */
       
  2009 public void setXORMode(boolean xor) {
       
  2010     if (handle == 0) {
       
  2011         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  2012     }
       
  2013     if (xor) {
       
  2014         if (data.xorMode == GCData.XOR_MODE_ON) {
       
  2015             return;
       
  2016         }
       
  2017         data.xorMode = GCData.XOR_MODE_ON;
       
  2018         data.internalGc.setBlendingMode(GraphicsContext.BLENDING_MODE_XOR);
       
  2019     } else {
       
  2020         if (data.xorMode == GCData.XOR_MODE_OFF) {
       
  2021             return;
       
  2022         }
       
  2023         data.xorMode = GCData.XOR_MODE_OFF;
       
  2024         data.internalGc.setBlendingMode(GraphicsContext.BLENDING_MODE_SRC_OVER);
       
  2025     }
       
  2026 }
       
  2027 
       
  2028 /**
       
  2029  * Returns the extent of the given string. No tab expansion or carriage return
       
  2030  * processing will be performed.
       
  2031  * <p>
       
  2032  * The <em>extent</em> of a string is the width and height of the rectangular
       
  2033  * area it would cover if drawn in a particular font (in this case, the current
       
  2034  * font in the receiver).
       
  2035  * </p>
       
  2036  * 
       
  2037  * @param string
       
  2038  *            the string to measure
       
  2039  * @return a point containing the extent of the string
       
  2040  * 
       
  2041  * @exception IllegalArgumentException
       
  2042  *                <ul>
       
  2043  *                <li>ERROR_NULL_ARGUMENT - if the string is null</li>
       
  2044  *                </ul>
       
  2045  * @exception SWTException
       
  2046  *                <ul>
       
  2047  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  2048  *                </li>
       
  2049  *                </ul>
       
  2050  */
       
  2051 public Point stringExtent(String string) {
       
  2052     return textExtent(string, 0);
       
  2053 }
       
  2054 
       
  2055 /**
       
  2056  * Returns the extent of the given string. Tab expansion and carriage return
       
  2057  * processing are performed.
       
  2058  * <p>
       
  2059  * The <em>extent</em> of a string is the width and height of the rectangular
       
  2060  * area it would cover if drawn in a particular font (in this case, the current
       
  2061  * font in the receiver).
       
  2062  * </p>
       
  2063  * 
       
  2064  * @param string
       
  2065  *            the string to measure
       
  2066  * @return a point containing the extent of the string
       
  2067  * 
       
  2068  * @exception IllegalArgumentException
       
  2069  *                <ul>
       
  2070  *                <li>ERROR_NULL_ARGUMENT - if the string is null</li>
       
  2071  *                </ul>
       
  2072  * @exception SWTException
       
  2073  *                <ul>
       
  2074  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  2075  *                </li>
       
  2076  *                </ul>
       
  2077  */
       
  2078 public Point textExtent(String string) {
       
  2079     return textExtent(string, SWT.DRAW_DELIMITER | SWT.DRAW_TAB);
       
  2080 }
       
  2081 
       
  2082 /**
       
  2083  * Returns the extent of the given string. Tab expansion, line delimiter and
       
  2084  * mnemonic processing are performed according to the specified flags, which can
       
  2085  * be a combination of:
       
  2086  * <dl>
       
  2087  * <dt><b>DRAW_DELIMITER</b></dt>
       
  2088  * <dd>draw multiple lines</dd>
       
  2089  * <dt><b>DRAW_TAB</b></dt>
       
  2090  * <dd>expand tabs</dd>
       
  2091  * <dt><b>DRAW_MNEMONIC</b></dt>
       
  2092  * <dd>underline the mnemonic character</dd>
       
  2093  * <dt><b>DRAW_TRANSPARENT</b></dt>
       
  2094  * <dd>transparent background</dd>
       
  2095  * </dl>
       
  2096  * <p>
       
  2097  * The <em>extent</em> of a string is the width and height of the rectangular
       
  2098  * area it would cover if drawn in a particular font (in this case, the current
       
  2099  * font in the receiver).
       
  2100  * </p>
       
  2101  * 
       
  2102  * @param string
       
  2103  *            the string to measure
       
  2104  * @param flags
       
  2105  *            the flags specifying how to process the text
       
  2106  * @return a point containing the extent of the string
       
  2107  * 
       
  2108  * @exception IllegalArgumentException
       
  2109  *                <ul>
       
  2110  *                <li>ERROR_NULL_ARGUMENT - if the string is null</li>
       
  2111  *                </ul>
       
  2112  * @exception SWTException
       
  2113  *                <ul>
       
  2114  *                <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
       
  2115  *                </li>
       
  2116  *                </ul>
       
  2117  */
       
  2118 public Point textExtent(String string, int flags) {
       
  2119     if (handle == 0)
       
  2120         SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
       
  2121     if (string == null)
       
  2122         SWT.error(SWT.ERROR_NULL_ARGUMENT);
       
  2123 
       
  2124     int[] box = new int[4];
       
  2125     int textFlags = 0;
       
  2126 
       
  2127     if ((flags & SWT.DRAW_DELIMITER) == 0) {
       
  2128         textFlags |= GraphicsContext.TEXT_SINGLE_LINE;
       
  2129     }
       
  2130     if ((flags & SWT.DRAW_TAB) != 0) {
       
  2131         textFlags |= GraphicsContext.TEXT_EXPAND_TABS;
       
  2132     }
       
  2133     if ((flags & SWT.DRAW_MNEMONIC) != 0) {
       
  2134         textFlags |= GraphicsContext.TEXT_SHOW_MNEMONIC;
       
  2135     }
       
  2136 
       
  2137     data.internalGc.getTextBoundingBox(box, string,
       
  2138             GraphicsContext.ALIGNMENT_LEFT, textFlags);
       
  2139 
       
  2140     return new Point(box[GraphicsContext.RECT_WIDTH],
       
  2141             box[GraphicsContext.RECT_HEIGHT]);
       
  2142 }
       
  2143 
       
  2144 /**
       
  2145  * Returns a string containing a concise, human-readable description of the
       
  2146  * receiver.
       
  2147  * 
       
  2148  * @return a string representation of the receiver
       
  2149  */
       
  2150 public String toString() {
       
  2151     if (isDisposed())
       
  2152         return "GC {*DISPOSED*}";
       
  2153     return "GC {" + handle + "}";
       
  2154 }
       
  2155 }