~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/ikvm/openjdk/sun/java2d/SunCompositeContext.java

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* AlphaCompositeContext.java -- CompositeContext impl for AlphaComposite
 
2
   Copyright (C) 2006 Free Software Foundation, Inc.
 
3
 
 
4
This file is part of GNU Classpath.
 
5
 
 
6
GNU Classpath is free software; you can redistribute it and/or modify
 
7
it under the terms of the GNU General Public License as published by
 
8
the Free Software Foundation; either version 2, or (at your option)
 
9
any later version.
 
10
 
 
11
GNU Classpath is distributed in the hope that it will be useful, but
 
12
WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
General Public License for more details.
 
15
 
 
16
You should have received a copy of the GNU General Public License
 
17
along with GNU Classpath; see the file COPYING.  If not, write to the
 
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
19
02110-1301 USA.
 
20
 
 
21
Linking this library statically or dynamically with other modules is
 
22
making a combined work based on this library.  Thus, the terms and
 
23
conditions of the GNU General Public License cover the whole
 
24
combination.
 
25
 
 
26
As a special exception, the copyright holders of this library give you
 
27
permission to link this library with independent modules to produce an
 
28
executable, regardless of the license terms of these independent
 
29
modules, and to copy and distribute the resulting executable under
 
30
terms of your choice, provided that you also meet, for each linked
 
31
independent module, the terms and conditions of the license of that
 
32
module.  An independent module is a module which is not derived from
 
33
or based on this library.  If you modify this library, you may extend
 
34
this exception to your version of the library, but you are not
 
35
obligated to do so.  If you do not wish to do so, delete this
 
36
exception statement from your version. */
 
37
 
 
38
 
 
39
package sun.java2d;
 
40
 
 
41
import java.awt.AWTError;
 
42
import java.awt.AlphaComposite;
 
43
import java.awt.CompositeContext;
 
44
import java.awt.image.ColorModel;
 
45
import java.awt.image.Raster;
 
46
import java.awt.image.WritableRaster;
 
47
 
 
48
/**
 
49
 * A CompositeContext implementation for {@link AlphaComposite}.
 
50
 *
 
51
 * @author Roman Kennke (kennke@aicas.com)
 
52
 */
 
53
public class SunCompositeContext
 
54
  implements CompositeContext
 
55
{
 
56
 
 
57
  /**
 
58
   * The Composite object for which we perform compositing.
 
59
   */
 
60
  private AlphaComposite composite;
 
61
 
 
62
  /**
 
63
   * The source color model.
 
64
   */
 
65
  private ColorModel srcColorModel;
 
66
 
 
67
  /**
 
68
   * The destination color model.
 
69
   */
 
70
  private ColorModel dstColorModel;
 
71
 
 
72
  /**
 
73
   * The blending factor for the source.
 
74
   */
 
75
  private float fs;
 
76
 
 
77
  /**
 
78
   * The blending factor for the destination.
 
79
   */
 
80
  private float fd;
 
81
 
 
82
  /**
 
83
   * Creates a new AlphaCompositeContext.
 
84
   *
 
85
   * @param aComp the AlphaComposite object 
 
86
   * @param srcCM the source color model
 
87
   * @param dstCM the destination color model
 
88
   */
 
89
  public SunCompositeContext(AlphaComposite aComp, ColorModel srcCM,
 
90
                               ColorModel dstCM)
 
91
  {
 
92
    composite = aComp;
 
93
    srcColorModel = srcCM;
 
94
    dstColorModel = dstCM;
 
95
 
 
96
    
 
97
    // Determine the blending factors according to the rule in the
 
98
    // AlphaComposite. For some rules the factors must be determined
 
99
    // dynamically because they depend on the actual pixel value.
 
100
    switch (composite.getRule())
 
101
    {
 
102
      case AlphaComposite.CLEAR:
 
103
        fs = 0.F;
 
104
        fd= 0.F;
 
105
        break;
 
106
      case AlphaComposite.DST:
 
107
        fs = 0.F;
 
108
        fd= 1.F;
 
109
        break;
 
110
      case AlphaComposite.DST_ATOP:
 
111
        fs = 1.F; // Determined later as 1 - alpha_dst;
 
112
        fd = 1.F; // Determined later as alpha_src;
 
113
        break;
 
114
      case AlphaComposite.DST_IN:
 
115
        fs = 0.F;
 
116
        fd = 0.F; // Determined later as alpha_src;
 
117
        break;
 
118
      case AlphaComposite.DST_OUT:
 
119
        fs = 0.F;
 
120
        fd = 0.F; // Determined later as 1 - alpha_src;
 
121
        break;
 
122
      case AlphaComposite.DST_OVER:
 
123
        fs = 1.F; // Determined later as 1 - alpha_dst.
 
124
        fd= 1.F;
 
125
        break;
 
126
      case AlphaComposite.SRC:
 
127
        fs = 1.F;
 
128
        fd= 0.F;
 
129
        break;
 
130
      case AlphaComposite.SRC_ATOP:
 
131
        fs = 1.F; // Determined later as alpha_dst;
 
132
        fd = 1.F; // Determined later as 1 - alpha_src;
 
133
        break;
 
134
      case AlphaComposite.SRC_IN:
 
135
        fs = 0.F; // Determined later as alpha_dst;
 
136
        fd = 0.F;
 
137
        break;
 
138
      case AlphaComposite.SRC_OUT:
 
139
        fs = 0.F; // Determined later as 1 - alpha_dst;
 
140
        fd = 0.F;
 
141
        break;
 
142
      case AlphaComposite.SRC_OVER:
 
143
        fs = 1.F;
 
144
        fd= 1.F; // Determined later as 1 - alpha_src.
 
145
        break;
 
146
      case AlphaComposite.XOR:
 
147
        fs = 1.F; // Determined later as 1 - alpha_dst.
 
148
        fd= 1.F; // Determined later as 1 - alpha_src.
 
149
        break;
 
150
      default:
 
151
        throw new AWTError("Illegal AlphaComposite rule");
 
152
    }
 
153
 
 
154
  }
 
155
 
 
156
  /**
 
157
   * Releases all resources held by this composite object.
 
158
   */
 
159
  public void dispose()
 
160
  {
 
161
    // Nothing to do here yet.
 
162
  }
 
163
 
 
164
  /**
 
165
   * Performs compositing according to the rules specified in the
 
166
   * AlphaComposite from the constructor.
 
167
   */
 
168
  public void compose(Raster src, Raster dstIn, WritableRaster dstOut)
 
169
  {
 
170
 
 
171
    // TODO: This implementation is very general and highly inefficient. There
 
172
    // are two possible ways to optimize this:
 
173
    // 1. Special cased implementations for common ColorModels and transfer
 
174
    //    types.
 
175
    // 2. Native implementation.
 
176
 
 
177
    int x0 = src.getMinX();
 
178
    int y0 = src.getMinY();
 
179
    int width = src.getWidth();
 
180
    int height = src.getHeight();
 
181
    int x1 = x0 + width;
 
182
    int y1 = y0 + height;
 
183
 
 
184
    Object srcPixel = null;
 
185
    Object dstPixel = null;
 
186
 
 
187
    // Prepare the array that holds the color and alpha components of the
 
188
    // source pixels.
 
189
    float[] srcComponents;
 
190
    int srcComponentsLength = srcColorModel.getNumComponents();
 
191
    if (! srcColorModel.hasAlpha())
 
192
      srcComponentsLength += 1;
 
193
    srcComponents = new float[srcComponentsLength];
 
194
 
 
195
    // Prepare the array that holds the color and alpha components of the
 
196
    // destination pixels.
 
197
    float[] dstComponents;
 
198
    int dstComponentsLength = dstColorModel.getNumComponents();
 
199
    if (! dstColorModel.hasAlpha())
 
200
      dstComponentsLength += 1;
 
201
    dstComponents = new float[dstComponentsLength];
 
202
 
 
203
    if (srcComponentsLength != dstComponentsLength)
 
204
      throw new AWTError("The color models of the source and destination have"
 
205
                         + "incompatible number of color components");
 
206
 
 
207
    int srcTransferType = srcColorModel.getTransferType();
 
208
    int dstTransferType = dstColorModel.getTransferType();
 
209
 
 
210
    for (int y = y0; y < y1; y++)
 
211
      {
 
212
        for (int x = x0; x < x1; x++)
 
213
          {
 
214
            // Fetch source pixel.
 
215
            srcPixel = src.getDataElements(x, y, (int[]) srcPixel);
 
216
            // Fetch destination pixel.
 
217
            dstPixel = dstIn.getDataElements(x, y, dstPixel);
 
218
            // Get normalized components. This is the only type that is
 
219
            // guaranteed to be supported by all ColorModels.
 
220
            srcComponents =
 
221
              srcColorModel.getNormalizedComponents(srcPixel, srcComponents, 0);
 
222
            if (! srcColorModel.hasAlpha())
 
223
              srcComponents[srcComponentsLength - 1] = 1.0F;
 
224
            dstComponents =
 
225
              dstColorModel.getNormalizedComponents(dstPixel, dstComponents, 0);
 
226
            if (! dstColorModel.hasAlpha())
 
227
              dstComponents[dstComponentsLength - 1] = 1.0F;
 
228
 
 
229
            // Prepare the input.
 
230
            float compositeAlpha = composite.getAlpha();
 
231
            srcComponents[srcComponentsLength - 1] *= compositeAlpha;
 
232
            if (srcColorModel.isAlphaPremultiplied())
 
233
              {
 
234
                for (int i = srcComponentsLength - 2; i >= 0; i--)
 
235
                  srcComponents[i] *= compositeAlpha;
 
236
              }
 
237
            else
 
238
              {
 
239
                for (int i = srcComponentsLength - 2; i >= 0; i--)
 
240
                  srcComponents[i] *= srcComponents[srcComponentsLength - 1];
 
241
              }
 
242
            if (! dstColorModel.isAlphaPremultiplied())
 
243
              {
 
244
                for (int i = dstComponentsLength - 2; i >= 0; i--)
 
245
                  dstComponents[i] *= dstComponents[dstComponents.length - 1];
 
246
              }
 
247
 
 
248
            // Determine the blending factors according to the rule in the
 
249
            // AlphaComposite. For some rules the factors must be determined
 
250
            // dynamically because they depend on the actual pixel value.
 
251
            float srcAlpha = srcComponents[srcComponentsLength - 1];
 
252
            float dstAlpha = dstComponents[dstComponentsLength - 1];
 
253
            switch (composite.getRule())
 
254
            {
 
255
              case AlphaComposite.DST_ATOP:
 
256
                fs = 1.F - dstAlpha;
 
257
                fd = srcAlpha;
 
258
                break;
 
259
              case AlphaComposite.DST_IN:
 
260
                fd = srcAlpha;
 
261
                break;
 
262
              case AlphaComposite.DST_OUT:
 
263
                fd = 1.F - srcAlpha;
 
264
                break;
 
265
              case AlphaComposite.DST_OVER:
 
266
                fs = 1.F - dstAlpha;
 
267
                break;
 
268
              case AlphaComposite.SRC_ATOP:
 
269
                fs = srcAlpha;
 
270
                fd = 1.F - srcAlpha;
 
271
                break;
 
272
              case AlphaComposite.SRC_IN:
 
273
                fs = dstAlpha;
 
274
                break;
 
275
              case AlphaComposite.SRC_OUT:
 
276
                fs = 1.F - dstAlpha;
 
277
                break;
 
278
              case AlphaComposite.SRC_OVER:
 
279
                fd= 1.F - srcAlpha;
 
280
                break;
 
281
              case AlphaComposite.XOR:
 
282
                fs = 1.F - dstAlpha;
 
283
                fd= 1.F - srcAlpha;
 
284
                break;
 
285
              default:
 
286
                // For the other cases the factors have already been determined
 
287
                // in the constructor.
 
288
            }
 
289
 
 
290
            // Apply the blending equation to the pixels.
 
291
            for (int i = 0; i < srcComponentsLength; i++)
 
292
              {
 
293
                dstComponents[i] = srcComponents[i] * fs
 
294
                                   + dstComponents[i] * fd;
 
295
              }
 
296
 
 
297
            // Convert the result back when the destination is not
 
298
            // alpha-premultiplied.
 
299
            dstAlpha = dstComponents[dstComponentsLength - 1];
 
300
            if (!dstColorModel.isAlphaPremultiplied() && dstAlpha != 0.F)
 
301
              {
 
302
                for (int i = 0; i < dstComponentsLength - 1; i++)
 
303
                  {
 
304
                    dstComponents[i] = dstComponents[i] / dstAlpha; 
 
305
                  }
 
306
              }
 
307
 
 
308
            // Store the result in the destination raster.
 
309
            dstPixel = dstColorModel.getDataElements(dstComponents, 0,
 
310
                                                     dstPixel);
 
311
            dstOut.setDataElements(x, y, dstPixel);
 
312
          } // End X loop.
 
313
      } // End Y loop.
 
314
  }
 
315
 
 
316
}