Home » openjdk-7 » java » awt » [javadoc | source]

    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one or more
    3    *  contributor license agreements.  See the NOTICE file distributed with
    4    *  this work for additional information regarding copyright ownership.
    5    *  The ASF licenses this file to You under the Apache License, Version 2.0
    6    *  (the "License"); you may not use this file except in compliance with
    7    *  the License.  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    *  Unless required by applicable law or agreed to in writing, software
   12    *  distributed under the License is distributed on an "AS IS" BASIS,
   13    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    *  See the License for the specific language governing permissions and
   15    *  limitations under the License.
   16    */
   17   /**
   18    * @author Pavel Dolgov
   19    */
   20   package java.awt;
   21   
   22   import java.awt.event.PaintEvent;
   23   import java.util.IdentityHashMap;
   24   import java.util.Map;
   25   import java.util.Map.Entry;
   26   
   27   import org.apache.harmony.awt.ClipRegion;
   28   import org.apache.harmony.awt.gl.MultiRectArea;
   29   
   30   
   31   /**
   32    * The collection of component regions that need to be painted
   33    */
   34   class RedrawManager {
   35   
   36       final Window window;
   37   
   38       private boolean paintNeeded;
   39       private boolean updateNeeded;
   40   
   41       private final Map<Component, MultiRectArea> paintRegions = new IdentityHashMap<Component, MultiRectArea>();
   42       private final Map<Component, MultiRectArea> updateRegions = new IdentityHashMap<Component, MultiRectArea>();
   43   
   44   
   45       public RedrawManager(Window window) {
   46           this.window = window;
   47       }
   48   
   49   
   50       public void addPaintRegion(Component c, Rectangle r) {
   51           synchronized(this) {
   52               addRegion(paintRegions, c, r);
   53               paintNeeded = true;
   54           }
   55       }
   56   
   57       public void addPaintRegion(Component c, MultiRectArea r) {
   58           synchronized(this) {
   59               addRegion(paintRegions, c, r);
   60               paintNeeded = true;
   61           }
   62       }
   63   
   64       public void addUpdateRegion(Component c, Rectangle r) {
   65           synchronized(this) {
   66               addRegion(updateRegions, c, r);
   67               updateNeeded = true;
   68           }
   69       }
   70   
   71       public void addUpdateRegion(Component c, MultiRectArea r) {
   72           synchronized(this) {
   73               addRegion(updateRegions, c, r);
   74               updateNeeded = true;
   75           }
   76       }
   77   
   78       public void addUpdateRegion(Component c) {
   79           addUpdateRegion(c, new Rectangle(0, 0, c.w, c.h));
   80       }
   81   
   82       /**
   83        * Post paint events to the queue, with the clip from paintRegions
   84        */
   85       private void doPaint() {
   86           postEvents(paintRegions, PaintEvent.PAINT);
   87           paintRegions.clear();
   88           paintNeeded = false;
   89       }
   90   
   91   
   92       /**
   93        * Translate update regions to HW ancestor,
   94        * then post update events to the queue, with the clip from updateRegions
   95        */
   96       private void doUpdate() {
   97           synchronized(this) {
   98               postEvents(updateRegions, PaintEvent.UPDATE);
   99               updateRegions.clear();
  100               updateNeeded = false;
  101           }
  102       }
  103   
  104       private static void addRegion(Map<Component, MultiRectArea> map, Component c, Rectangle r) {
  105           MultiRectArea area = map.get(c);
  106           if (area != null) {
  107               area.add(r);
  108           } else {
  109               area = new MultiRectArea(r);
  110               map.put(c, area);
  111           }
  112   
  113       }
  114   
  115       private static void addRegion(Map<Component, MultiRectArea> map, Component c, MultiRectArea r) {
  116           MultiRectArea area = map.get(c);
  117           if (area != null) {
  118               area.add(r);
  119           } else {
  120               area = new MultiRectArea(r);
  121               map.put(c, area);
  122           }
  123   
  124       }
  125   
  126       public boolean redrawAll() {
  127           synchronized(this) {
  128               subtractPaintFromUpdate();
  129   
  130               boolean result = paintNeeded;
  131               if (paintNeeded) {
  132                   doPaint();
  133               }
  134               if (updateNeeded) {
  135                   doUpdate();
  136               }
  137               return result;
  138           }
  139       }
  140   
  141       private void subtractPaintFromUpdate() {
  142           for (Object name : paintRegions.entrySet()) {
  143               Map.Entry<?, ?> entry = (Entry<?, ?>)name;
  144               Component c = (Component) entry.getKey();
  145               MultiRectArea paint = (MultiRectArea) entry.getValue();
  146               MultiRectArea update = updateRegions.get(c);
  147               if (update == null) {
  148                   continue;
  149               }
  150               update.substract(paint);
  151               if (update.isEmpty()) {
  152                   updateRegions.remove(c);
  153               }
  154           }
  155       }
  156   
  157   
  158       /**
  159        * Post paint events for the collected regions
  160        * @param regions - Map<Component, MultiRectArea> - 
  161        *      regions that need to be painted
  162        * @param eventId - PaintEvent.PAINT or PaintEvent.UPDATE
  163        */
  164       private static void postEvents(Map<Component, MultiRectArea> regions, int eventId) {
  165           for (Object name : regions.entrySet()) {
  166               Map.Entry<?, ?> entry = (Entry<?, ?>)name;
  167               Component c = (Component) entry.getKey();
  168               if (!c.visible || !c.behaviour.isDisplayable()) {
  169                   continue;
  170               }
  171               MultiRectArea clip = (MultiRectArea)entry.getValue();
  172               if (!clip.isEmpty()) {
  173                   postPaintEvent(c, clip, eventId);
  174               }
  175           }
  176       }
  177   
  178       private static void postPaintEvent(Component c, MultiRectArea clip, int eventId) {
  179           PaintEvent event = new PaintEvent(c, eventId,
  180                   new ClipRegion(clip));
  181           c.toolkit.getSystemEventQueueImpl().postEvent(event);
  182       }
  183   
  184   
  185       /**
  186        * Subtract the component's region that waits for painting
  187        * from the provided component's area.
  188        * 
  189        * @return the resulting region, or null if the result is empty
  190        */
  191       public MultiRectArea subtractPendingRepaintRegion(Component c, MultiRectArea mra) {
  192           if (mra.isEmpty()) {
  193               return null;
  194           }
  195           int x = 0, y = 0;
  196           while (c != null && c.behaviour.isLightweight()) {
  197               x += c.x;
  198               y += c.y;
  199               c = c.parent;
  200           }
  201           if (c == null) {
  202               return null;
  203           }
  204   
  205           synchronized(this) {
  206               // Now c is heavyweight for sure
  207               MultiRectArea paint = paintRegions.get(c);
  208               MultiRectArea update = updateRegions.get(c);
  209   
  210               if (paint == null && update == null) {
  211                   return mra;
  212               }
  213               MultiRectArea diff = new MultiRectArea(mra);
  214               diff.translate(x, y);
  215   
  216               if (paint != null) {
  217                   diff.substract(paint);
  218               }
  219               if (update != null) {
  220                   diff.substract(update);
  221               }
  222               if (diff.isEmpty()) {
  223                   return null;
  224               }
  225               diff.translate(-x, -y);
  226               return diff;
  227           }
  228       }
  229   }

Home » openjdk-7 » java » awt » [javadoc | source]