javauis/lcdui_qt/src/javax/microedition/lcdui/Buffer.java
changeset 26 dc7c549001d5
child 35 85266cc22c7f
equal deleted inserted replaced
23:98ccebc37403 26:dc7c549001d5
       
     1 /*
       
     2 * Copyright (c) 2009,2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 package javax.microedition.lcdui;
       
    18 
       
    19 import org.eclipse.swt.widgets.Control;
       
    20 import org.eclipse.swt.graphics.Point;
       
    21 import org.eclipse.swt.graphics.Rectangle;
       
    22 import org.eclipse.swt.internal.qt.graphics.GraphicsContext;
       
    23 import org.eclipse.swt.internal.qt.graphics.JavaCommandBuffer;
       
    24 import org.eclipse.swt.internal.qt.graphics.WindowSurface;
       
    25 
       
    26 /**
       
    27  * This class works a proxy between instances of Graphics class and common graphics
       
    28  * (command buffer and GraphicsContext). The relation of this class to Graphics is one-to-many, i.e.
       
    29  * one GraphicsBuffer instance handles multiple Graphics instances.
       
    30  *
       
    31  * Each LCDUI API class instance providing access to Graphics (Image, Canvas, GameCanvas, CustomItem),
       
    32  * must instantiate one GraphicsBuffer and use it for creating instances of Graphics class.
       
    33  *
       
    34  * The implementation is not thread safe, thus all serialization must be implemented in
       
    35  * callers, for instance the Graphics implementation serializes all calls to this class.
       
    36  * Furthermore this class does not take care of switching to UI thread, it must be done by
       
    37  * caller object.
       
    38  */
       
    39 
       
    40 abstract class Buffer
       
    41 {
       
    42 
       
    43     // Constants for buffer host types
       
    44     final static int HOST_TYPE_IMAGE = 1;
       
    45     final static int HOST_TYPE_CANVAS = 2;
       
    46     final static int HOST_TYPE_CUSTOMITEM = 3;
       
    47 
       
    48     // Flags for raising settings validation
       
    49     private final static int NONE            = 0;
       
    50     private final static int COLOR           = 1;
       
    51     private final static int CLIP            = 2;
       
    52     private final static int FONT            = 4;
       
    53     private final static int STROKESTYLE     = 8;
       
    54     private final static int COORS_TRANSLATION = 16;
       
    55 
       
    56     // Graphics settings active in buffer
       
    57     // all values are comparable to those
       
    58     // in Graphics except font which is stored
       
    59     // as handle instead of LCDUI Font
       
    60     private int bufferFontHandle;
       
    61     private int bufferColor;
       
    62     private int bufferStrokeStyle;
       
    63     private int bufferTranslateX;
       
    64     private int bufferTranslateY;
       
    65     private Rectangle bufferClip;
       
    66 
       
    67     private GraphicsContext gc;
       
    68     private JavaCommandBuffer commandBuffer;
       
    69     private Rectangle hostBounds;
       
    70     private Graphics currentClient;
       
    71     private boolean started;
       
    72     private int clientCount;
       
    73 
       
    74     // The target window surface where this
       
    75     // instance flushes draw primitives
       
    76     WindowSurface windowSurface;
       
    77 
       
    78     /**
       
    79      * Constructor
       
    80      */
       
    81     protected Buffer()
       
    82     {
       
    83         hostBounds = new Rectangle(0,0,0,0);
       
    84         bufferClip = new Rectangle(0,0,0,0);
       
    85         bufferFontHandle = 0;
       
    86         bufferColor = 0xff000000;
       
    87         bufferStrokeStyle = Graphics.SOLID;
       
    88         bufferTranslateX = 0;
       
    89         bufferTranslateY = 0;
       
    90     }
       
    91 
       
    92     /**
       
    93      * Initializes data, called once
       
    94      */
       
    95     void init()
       
    96     {
       
    97         clientCount = 0;
       
    98         gc = new GraphicsContext();
       
    99         commandBuffer = new JavaCommandBuffer();
       
   100         gc.bindTarget(commandBuffer);
       
   101         writeControlBoundsToBuffer(false);
       
   102         started = true;
       
   103     }
       
   104 
       
   105     /**
       
   106      * Defines the bounds of the host.
       
   107      * Bounds are used for restricting the rendering in
       
   108      * the area of the control that is being updated. With Images
       
   109      * the bounds are not used.
       
   110      *
       
   111      * @param crtl The Control of the host
       
   112      * @param clienArea The area of the control which can be drawn by Graphics
       
   113      */
       
   114     void setControlBounds(final Control control)
       
   115     {
       
   116         ESWTUIThreadRunner.safeSyncExec(new Runnable()
       
   117         {
       
   118             public void run()
       
   119             {
       
   120                 // This implementation is based on the fact that
       
   121                 // the QWindowSurface has the size of the shell active area
       
   122                 // not the whole display, thus Shell clientArea equals QWindowSurface.
       
   123                 // This might change in future if/when Qt starts
       
   124                 // rendering e.g. the status pane i.e. the whole display
       
   125                 // to window surface
       
   126                 Point controlLoc = control.toDisplay(0,0);
       
   127                 Point shellLoc = control.getShell().toDisplay(0,0);
       
   128                 hostBounds.x = controlLoc.x - shellLoc.x;
       
   129                 hostBounds.y = controlLoc.y - shellLoc.y;
       
   130                 hostBounds.width = control.getBounds().width;
       
   131                 hostBounds.height = control.getBounds().height;
       
   132             }
       
   133         });
       
   134     }
       
   135 
       
   136     /**
       
   137      * Performs binding to target in host specific way
       
   138      */
       
   139     abstract void bindToHost(GraphicsContext gc);
       
   140 
       
   141     /**
       
   142      * Getter for the host of the buffer
       
   143      * @return The host
       
   144      */
       
   145     abstract Object getHost();
       
   146 
       
   147     /**
       
   148      * Getter for the host type
       
   149      * @return One of host types defined in this class
       
   150      */
       
   151     abstract int getHostType();
       
   152 
       
   153     /**
       
   154      *  Setups the window surface if not setup already.
       
   155      *  This method must be called before flushing buffer to
       
   156      *  window surface
       
   157      *  Note. must be called in UI thread
       
   158      */
       
   159     abstract void setupWindowSurface();
       
   160 
       
   161     /**
       
   162      * Creates and returns new Graphics instance
       
   163      * @return new Graphics instance
       
   164      */
       
   165     Graphics getGraphics()
       
   166     {
       
   167         if(!started)
       
   168         {
       
   169             init();
       
   170         }
       
   171         clientCount++;
       
   172         return new Graphics(this);
       
   173     }
       
   174 
       
   175     /**
       
   176      * Synchronizes this buffer with the actual target
       
   177      * must be called in UI thread. If no Graphics instances
       
   178      * are creates, sync has no effect
       
   179      */
       
   180     void sync()
       
   181     {
       
   182         if(!started)
       
   183         {
       
   184             return;
       
   185         }
       
   186         // if there's nothing to flush return
       
   187         if(!commandBuffer.containsDrawnPrimitives())
       
   188         {
       
   189             return;
       
   190         }
       
   191         doRelease();
       
   192         bindToHost(gc);
       
   193         gc.render(commandBuffer);
       
   194         doRelease();
       
   195 
       
   196         // Reset commands
       
   197         commandBuffer.reset();
       
   198 
       
   199         // Write last settings to buffer
       
   200         // as they are reset in bind
       
   201         gc.bindTarget(commandBuffer);
       
   202         gc.setFont(bufferFontHandle);
       
   203         gc.setBackgroundColor(bufferColor, true);
       
   204         gc.setForegroundColor(bufferColor, true);
       
   205         writeControlBoundsToBuffer(true);
       
   206     }
       
   207 
       
   208     /**
       
   209      * Decreases the client reference count,
       
   210      * should be called by Graphics instances when
       
   211      * they are about to be disposed
       
   212      */
       
   213     void removeRef()
       
   214     {
       
   215         clientCount--;
       
   216     }
       
   217 
       
   218     /**
       
   219      * Disposes this instance
       
   220      */
       
   221     void dispose()
       
   222     {
       
   223         doRelease();
       
   224         gc.dispose();
       
   225         gc = null;
       
   226         commandBuffer = null;
       
   227     }
       
   228 
       
   229     void copyArea(int x1, int y1, int width, int height, int x2, int y2, Graphics client)
       
   230     {
       
   231         gc.copyArea(x1, y1, width, height, x2, y2);
       
   232     }
       
   233 
       
   234     void fillRect(int x, int y, int w, int h, Graphics client)
       
   235     {
       
   236         validateAndApplySettings((COLOR|CLIP|COORS_TRANSLATION), client);
       
   237         gc.fillRect(x, y, w, h);
       
   238     }
       
   239 
       
   240     void fillRoundRect(int x, int y, int w, int h, int arcW, int arcH, Graphics client)
       
   241     {
       
   242         validateAndApplySettings((COLOR|CLIP|COORS_TRANSLATION), client);
       
   243         gc.fillRoundRect(x, y, w, h, arcW, arcH);
       
   244     }
       
   245 
       
   246     void fillArc(int x, int y, int w, int h, int startAngle, int arcAngle, Graphics client)
       
   247     {
       
   248         validateAndApplySettings((COLOR|CLIP|COORS_TRANSLATION), client);
       
   249         gc.fillArc(x, y, w, h, startAngle, arcAngle);
       
   250     }
       
   251 
       
   252     void fillTriangle(int[] points, Graphics client)
       
   253     {
       
   254         validateAndApplySettings((COLOR|CLIP|COORS_TRANSLATION), client);
       
   255         gc.fillPolygon(points);
       
   256     }
       
   257 
       
   258     void setClip(int x, int y, int w, int h, Graphics client)
       
   259     {
       
   260         validateAndApplySettings(COORS_TRANSLATION, client);
       
   261         // check if given clip is already active in buffer
       
   262         if((bufferClip.x == x) && (bufferClip.y == y) &&
       
   263                 (bufferClip.width == w) && (bufferClip.height== h))
       
   264         {
       
   265             return;
       
   266         }
       
   267         // Images do not need special handling
       
   268         if(getHostType() == HOST_TYPE_IMAGE)
       
   269         {
       
   270             gc.setClip(x, y, w, h, false);
       
   271             return;
       
   272         }
       
   273 
       
   274         // translate clip to display coordinates and apply
       
   275         Rectangle rect = clipToDisplayCoords(x, y, w, h);
       
   276         if(rect.isEmpty())
       
   277         {
       
   278             // check is buffer clip is already up to date
       
   279             if(bufferClip.isEmpty())
       
   280             {
       
   281                 return;
       
   282             }
       
   283             else
       
   284             {
       
   285                 // This is a special case, where the clip defines
       
   286                 // an area outside control bounds and due to that the clip
       
   287                 // is set to zero size, in order t prevent drawing on top of other controls.
       
   288                 // In all other cases the buffer clip is always set
       
   289                 // to the same values as the client, i.e. Graphics has.
       
   290                 // So by setting the bufferClip here to zero means that the clip
       
   291                 // in Graphics and the buffer are not in sync and not comparable,
       
   292                 // however they will be back in sync when client sets clip
       
   293                 // with an area partly or completely inside the host control.
       
   294                 bufferClip = rect;
       
   295             }
       
   296         }
       
   297         else
       
   298         {
       
   299             bufferClip.x = x;
       
   300             bufferClip.y = y;
       
   301             bufferClip.width = w;
       
   302             bufferClip.height = h;
       
   303         }
       
   304         gc.setClip(rect.x, rect.y, rect.width, rect.height, false);
       
   305     }
       
   306 
       
   307     void setColor(int r, int g, int b, Graphics client)
       
   308     {
       
   309         // check if given color is already active in buffer
       
   310         if(bufferColor == (Graphics.OPAQUE_ALPHA | (r << 16) | (g << 8) | b))
       
   311         {
       
   312             return;
       
   313         }
       
   314         gc.setForegroundColor(r, g, b);
       
   315         gc.setBackgroundColor(r, g, b);
       
   316 
       
   317         // Cache active color
       
   318         bufferColor = (Graphics.OPAQUE_ALPHA | (r << 16) | (g << 8) | b);
       
   319     }
       
   320 
       
   321     void setFont(int fontHandle, Graphics client)
       
   322     {
       
   323         // check if given font is already active in buffer
       
   324         if(bufferFontHandle == fontHandle)
       
   325         {
       
   326             return;
       
   327         }
       
   328         gc.setFont(fontHandle);
       
   329         // Cache active setting
       
   330         bufferFontHandle = fontHandle;
       
   331     }
       
   332 
       
   333     void setStrokeStyle(int cgfxStyle, int graphicsStyle, Graphics client)
       
   334     {
       
   335         if(bufferStrokeStyle == graphicsStyle)
       
   336         {
       
   337             return;
       
   338         }
       
   339         gc.setStrokeStyle(cgfxStyle);
       
   340         // Cache active setting
       
   341         bufferStrokeStyle = graphicsStyle;
       
   342     }
       
   343 
       
   344     void translate(int xDelta, int yDelta, Graphics client)
       
   345     {
       
   346         if((xDelta == 0) && (yDelta == 0))
       
   347         {
       
   348             return;
       
   349         }
       
   350         gc.translate(xDelta, yDelta);
       
   351         // Cache active settings
       
   352         bufferTranslateX += xDelta;
       
   353         bufferTranslateY += yDelta;
       
   354     }
       
   355 
       
   356     void drawLine(int xStart, int yStart, int xEnd, int yEnd, Graphics client)
       
   357     {
       
   358         validateAndApplySettings((COLOR|CLIP|COORS_TRANSLATION|STROKESTYLE), client);
       
   359         gc.drawLine(xStart, yStart, xEnd, yEnd);
       
   360     }
       
   361 
       
   362     void drawRect(int x, int y, int w, int h, Graphics client)
       
   363     {
       
   364         validateAndApplySettings((COLOR|CLIP|COORS_TRANSLATION|STROKESTYLE), client);
       
   365         gc.drawRect(x, y, w, h);
       
   366     }
       
   367 
       
   368     void drawRoundRect(int x, int y, int w, int h, int arcW, int arcH, Graphics client)
       
   369     {
       
   370         validateAndApplySettings((COLOR|CLIP|COORS_TRANSLATION|STROKESTYLE), client);
       
   371         gc.drawRoundRect(x, y, w, h, arcW, arcH);
       
   372     }
       
   373 
       
   374     void drawArc(int x, int y, int w, int h, int startAngle, int arcAngle, Graphics client)
       
   375     {
       
   376         validateAndApplySettings((COLOR|CLIP|COORS_TRANSLATION|STROKESTYLE), client);
       
   377         gc.drawArc(x, y, w, h, startAngle, arcAngle);
       
   378     }
       
   379 
       
   380     void drawString(String string, int x, int y, Graphics client)
       
   381     {
       
   382         validateAndApplySettings((COLOR|CLIP|COORS_TRANSLATION|FONT), client);
       
   383         gc.drawString(string, x, y, true);
       
   384     }
       
   385 
       
   386     void drawImage(org.eclipse.swt.internal.qt.graphics.Image image, int x,int y, Graphics client)
       
   387     {
       
   388         validateAndApplySettings((CLIP|COORS_TRANSLATION), client);
       
   389         gc.drawImage(image, x, y);
       
   390     }
       
   391 
       
   392     void drawImage(org.eclipse.swt.internal.qt.graphics.Image image, int xDst, int yDst,
       
   393                    int wDst, int hDst, int xSrc, int ySrc, int wSrc, int hSrc,
       
   394                    int transform, Graphics client)
       
   395     {
       
   396         validateAndApplySettings((CLIP|COORS_TRANSLATION), client);
       
   397         gc.drawImage(image, xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, transform);
       
   398     }
       
   399 
       
   400     void drawRGB(int[] rgb,
       
   401                  int offset,
       
   402                  int scanlength,
       
   403                  int x,
       
   404                  int y,
       
   405                  int w,
       
   406                  int h,
       
   407                  boolean alpha,
       
   408                  Graphics client)
       
   409     {
       
   410         validateAndApplySettings((CLIP|COORS_TRANSLATION), client);
       
   411         gc.drawRGB(rgb, offset, scanlength, x, y, w, h, alpha);
       
   412     }
       
   413 
       
   414     void drawRGB(int[] rgb,
       
   415                  int offset,
       
   416                  int scanlength,
       
   417                  int x,
       
   418                  int y,
       
   419                  int w,
       
   420                  int h,
       
   421                  boolean alpha,
       
   422                  int manipulation,
       
   423                  Graphics client)
       
   424     {
       
   425         validateAndApplySettings((CLIP|COORS_TRANSLATION), client);
       
   426         gc.drawRGB(rgb, offset, scanlength, x, y, w, h, alpha, manipulation);
       
   427     }
       
   428 
       
   429     void drawRGB(byte[] rgb,
       
   430                  byte[] transparencyMask,
       
   431                  int offset,
       
   432                  int scanlength,
       
   433                  int x,
       
   434                  int y,
       
   435                  int w,
       
   436                  int h,
       
   437                  int manipulation,
       
   438                  int format,
       
   439                  Graphics client)
       
   440     {
       
   441         validateAndApplySettings((CLIP|COORS_TRANSLATION), client);
       
   442         gc.drawRGB(rgb, transparencyMask, offset, scanlength, x, y, w, h, manipulation, format);
       
   443     }
       
   444 
       
   445     void drawRGB(short[] rgb,
       
   446                  int offset,
       
   447                  int scanlength,
       
   448                  int x,
       
   449                  int y,
       
   450                  int w,
       
   451                  int h,
       
   452                  boolean alpha,
       
   453                  int manipulation,
       
   454                  int format,
       
   455                  Graphics client)
       
   456     {
       
   457         validateAndApplySettings((CLIP|COORS_TRANSLATION), client);
       
   458         gc.drawRGB(rgb, offset, scanlength, x, y, w, h, alpha, manipulation, format);
       
   459     }
       
   460 
       
   461     void drawPolygon(int[] points, Graphics client)
       
   462     {
       
   463         validateAndApplySettings((COLOR|CLIP|COORS_TRANSLATION|STROKESTYLE), client);
       
   464         gc.drawPolygon(points);
       
   465     }
       
   466 
       
   467     void fillPolygon(int[] points, Graphics client)
       
   468     {
       
   469         validateAndApplySettings((COLOR|CLIP|COORS_TRANSLATION), client);
       
   470         gc.fillPolygon(points);
       
   471     }
       
   472 
       
   473     void setARGBColor(int argb, Graphics client)
       
   474     {
       
   475         if(bufferColor == argb)
       
   476         {
       
   477             return;
       
   478         }
       
   479         gc.setBackgroundColor(argb, true);
       
   480         gc.setForegroundColor(argb, true);
       
   481         // Cache active color
       
   482         bufferColor = argb;
       
   483     }
       
   484 
       
   485     /**
       
   486      * Translates given rectangle to window coordinates.
       
   487      * Coordinate system translation does not affect on this method.
       
   488      *
       
   489      * @param x The x-coordinate of the rectangle
       
   490      * @param y The y-coordinate of the rectangle
       
   491      * @param w The width of the rectangle
       
   492      * @param h The height of the rectangle
       
   493      * @return
       
   494      */
       
   495     Rectangle toWindowCoordinates(int x, int y, int w, int h)
       
   496     {
       
   497         final int xInDpy = hostBounds.x + x;
       
   498         final int yInDpy = hostBounds.y + y;
       
   499         return new Rectangle(xInDpy, yInDpy, xInDpy + w, yInDpy + h);
       
   500     }
       
   501 
       
   502 
       
   503     /**
       
   504      * Translates given rectangle to display/window surface coordinates
       
   505      * and outlines the clip inside the control bounds.
       
   506      *
       
   507      * @param x The x-coordinate of the rectangle
       
   508      * @param y The y-coordinate of the rectangle
       
   509      * @param w The width of the rectangle
       
   510      * @param h The height of the rectangle
       
   511      *
       
   512      */
       
   513     private Rectangle clipToDisplayCoords(int x, int y, int w, int h)
       
   514     {
       
   515         // Bottom-right corner of control bounds in window coordinates
       
   516         final int hostX2 = hostBounds.x + hostBounds.width;
       
   517         final int hostY2 = hostBounds.y + hostBounds.height;
       
   518         // clip in window coordinates
       
   519         final int clipX1Dpy = hostBounds.x + bufferTranslateX + x;
       
   520         final int clipY1Dpy = hostBounds.y + bufferTranslateY + y;
       
   521         final int clipX2Dpy = hostBounds.x + bufferTranslateX + x + w;
       
   522         final int clipY2Dpy = hostBounds.y + bufferTranslateY + y + h;
       
   523         int clipX1 = x;
       
   524         int clipY1 = y;
       
   525         int clipX2 = x + w;
       
   526         int clipY2 = y + h;
       
   527 
       
   528         // check if the clip is completely outside of control bounds
       
   529         if(!hostBounds.contains(clipX1Dpy, clipY1Dpy) && !hostBounds.contains(clipX2Dpy, clipY2Dpy))
       
   530         {
       
   531             return new Rectangle(0,0,0,0);
       
   532         }
       
   533 
       
   534         // At least one corner is inside control bounds so
       
   535         // adjust clip coordinates so that they lie within control bounds
       
   536         clipX1 = clipX1Dpy < hostBounds.x ? (x + (hostBounds.x - clipX1Dpy)) : x;
       
   537         clipX1 = clipX1Dpy > hostX2 ? (x - (clipX1Dpy - hostX2)) : x;
       
   538         clipY1 = clipY1Dpy < hostBounds.y ? (y + (hostBounds.y - clipY1Dpy)) : y;
       
   539         clipY1 = clipY1Dpy > hostY2 ? (y - (clipY1Dpy - hostY2)) : y;
       
   540 
       
   541         clipX2 = clipX2Dpy < hostBounds.x ? (clipX2 + (hostBounds.x - clipX1Dpy)) : clipX2;
       
   542         clipX2 = clipX2Dpy > hostX2 ? (clipX2 - (clipX1Dpy - hostX2)) : clipX2;
       
   543         clipY2 = clipY2Dpy < hostBounds.y ? (clipY2 + (hostBounds.y - clipY1Dpy)) : clipY2;
       
   544         clipY2 = clipY2Dpy > hostY2 ? (clipY2 - (clipY1Dpy - hostY2)) : clipY2;
       
   545 
       
   546         return new Rectangle(clipX1, clipY1, (clipX2 - clipX1) , (clipY1 - clipY2));
       
   547     }
       
   548 
       
   549     /**
       
   550      * Validates the current settings active in buffer against
       
   551      * caller settings and updated needed settings in buffer when
       
   552      * that is required. This method does not update anything if
       
   553      * there is only one (reference_count == 1)Graphics instance using this buffer.
       
   554      *
       
   555      * @param flags The settings that need to be checked
       
   556      * @param client The Graphics instance that made the call
       
   557      */
       
   558     private void validateAndApplySettings(int flags, Graphics client)
       
   559     {
       
   560         if(!clientChanged(client))
       
   561         {
       
   562             return;
       
   563         }
       
   564         if((COLOR & flags) != 0)
       
   565         {
       
   566             if(bufferColor != client.currentColor)
       
   567             {
       
   568                 gc.setBackgroundColor(client.currentColor, true);
       
   569                 gc.setForegroundColor(client.currentColor, true);
       
   570                 bufferColor = client.currentColor;
       
   571             }
       
   572         }
       
   573         if((CLIP & flags) != 0)
       
   574         {
       
   575             if(client.currentClip[0] != bufferClip.x &&
       
   576                     client.currentClip[1] != bufferClip.y &&
       
   577                     client.currentClip[2] != bufferClip.width &&
       
   578                     client.currentClip[3] != bufferClip.height)
       
   579             {
       
   580 
       
   581                 Rectangle rect = clipToDisplayCoords(client.currentClip[0], client.currentClip[1],
       
   582                                                      client.currentClip[2], client.currentClip[3]);
       
   583                 gc.setClip(rect.x, rect.y, rect.width, rect.height, false);
       
   584                 bufferClip.x = client.currentClip[0];
       
   585                 bufferClip.y = client.currentClip[1];
       
   586                 bufferClip.width = client.currentClip[2];
       
   587                 bufferClip.height = client.currentClip[3];
       
   588             }
       
   589         }
       
   590         if((COORS_TRANSLATION & flags) != 0)
       
   591         {
       
   592             if((bufferTranslateX != client.translateX) && (bufferTranslateY != client.translateY))
       
   593             {
       
   594                 gc.translate((client.translateX - bufferTranslateX), (client.translateY - bufferTranslateY));
       
   595                 bufferTranslateX = client.translateX;
       
   596                 bufferTranslateY = client.translateY;
       
   597             }
       
   598         }
       
   599         if((FONT & flags) != 0)
       
   600         {
       
   601             int fontHandle = Font.getESWTFont(client.currentFont).handle;
       
   602             if(bufferFontHandle != fontHandle)
       
   603             {
       
   604                 gc.setFont(fontHandle);
       
   605                 bufferFontHandle = fontHandle;
       
   606             }
       
   607         }
       
   608         if((STROKESTYLE & flags) != 0)
       
   609         {
       
   610             if(bufferStrokeStyle != client.currentStrokeSyle)
       
   611             {
       
   612                 gc.setStrokeStyle(Graphics.mapStrokeStyle(client.currentStrokeSyle));
       
   613                 bufferStrokeStyle = client.currentStrokeSyle;
       
   614             }
       
   615         }
       
   616     }
       
   617 
       
   618     private boolean clientChanged(Graphics client)
       
   619     {
       
   620         if(clientCount == 1)
       
   621         {
       
   622             return false;
       
   623         }
       
   624         if(currentClient != client)
       
   625         {
       
   626             currentClient = client;
       
   627             return true;
       
   628         }
       
   629         return false;
       
   630     }
       
   631 
       
   632     /**
       
   633      * Writes control bounds to buffer, including translation and clip
       
   634      * @param writeClientTranslation If true write also client translation to buffer, otherwise not
       
   635      */
       
   636     private void writeControlBoundsToBuffer(boolean writeClientTranslation)
       
   637     {
       
   638         if((hostBounds.x != 0) || (hostBounds.y != 0))
       
   639         {
       
   640             gc.translate(hostBounds.x, hostBounds.y);
       
   641         }
       
   642         gc.setClip(0, 0, hostBounds.width, hostBounds.height, false);
       
   643         // Cache buffer settings
       
   644         bufferClip.x = 0;
       
   645         bufferClip.y = 0;
       
   646         bufferClip.width = hostBounds.width;
       
   647         bufferClip.height = hostBounds.height;
       
   648         // write client translation if requested
       
   649         if(writeClientTranslation)
       
   650         {
       
   651             if((bufferTranslateX != 0) || (bufferTranslateY != 0))
       
   652             {
       
   653                 gc.translate(bufferTranslateX, bufferTranslateY);
       
   654             }
       
   655         }
       
   656     }
       
   657 
       
   658     private void doRelease()
       
   659     {
       
   660         gc.releaseTarget();
       
   661     }
       
   662 }