PageRenderTime 37ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/prism-common/src/com/sun/prism/impl/shape/OpenPiscesRasterizer.java

https://bitbucket.org/rbair/rbair-controls-8
Java | 226 lines | 169 code | 21 blank | 36 comment | 29 complexity | bf7ea3cb56cc6a9c8a4e5ee109d94e83 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, GPL-2.0, LGPL-2.0
  1. /*
  2. * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  3. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4. *
  5. * This code is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License version 2 only, as
  7. * published by the Free Software Foundation. Oracle designates this
  8. * particular file as subject to the "Classpath" exception as provided
  9. * by Oracle in the LICENSE file that accompanied this code.
  10. *
  11. * This code is distributed in the hope that it will be useful, but WITHOUT
  12. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  14. * version 2 for more details (a copy is included in the LICENSE file that
  15. * accompanied this code).
  16. *
  17. * You should have received a copy of the GNU General Public License version
  18. * 2 along with this work; if not, write to the Free Software Foundation,
  19. * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20. *
  21. * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22. * or visit www.oracle.com if you need additional information or have any
  23. * questions.
  24. */
  25. package com.sun.prism.impl.shape;
  26. import com.sun.javafx.geom.RectBounds;
  27. import com.sun.javafx.geom.Path2D;
  28. import com.sun.javafx.geom.Rectangle;
  29. import com.sun.javafx.geom.Shape;
  30. import com.sun.javafx.geom.transform.BaseTransform;
  31. import com.sun.openpisces.AlphaConsumer;
  32. import com.sun.openpisces.Renderer;
  33. import com.sun.prism.BasicStroke;
  34. import com.sun.prism.impl.PrismSettings;
  35. import java.nio.ByteBuffer;
  36. public class OpenPiscesRasterizer implements ShapeRasterizer {
  37. private static MaskData emptyData = MaskData.create(new byte[1], 0, 0, 1, 1);
  38. private static Consumer savedConsumer;
  39. @Override
  40. public MaskData getMaskData(Shape shape,
  41. BasicStroke stroke,
  42. RectBounds xformBounds,
  43. BaseTransform xform,
  44. boolean close)
  45. {
  46. if (stroke != null && stroke.getType() != BasicStroke.TYPE_CENTERED) {
  47. // RT-27427
  48. // TODO: Optimize the combinatorial strokes for simple
  49. // shapes and/or teach the rasterizer to be able to
  50. // do a "differential fill" between two shapes.
  51. // Note that most simple shapes will use a more optimized path
  52. // than this method for the INNER/OUTER strokes anyway.
  53. shape = stroke.createStrokedShape(shape);
  54. stroke = null;
  55. }
  56. if (xformBounds == null) {
  57. if (stroke != null) {
  58. // Note that all places that pass null for xformbounds also
  59. // pass null for stroke so that the following is not typically
  60. // executed, but just here as a safety net.
  61. shape = stroke.createStrokedShape(shape);
  62. stroke = null;
  63. }
  64. xformBounds = new RectBounds();
  65. //TODO: Need to verify that this is a safe cast ... (RT-27427)
  66. xformBounds = (RectBounds) xform.transform(shape.getBounds(), xformBounds);
  67. }
  68. Rectangle rclip = new Rectangle(xformBounds);
  69. if (rclip.isEmpty()) {
  70. return emptyData;
  71. }
  72. Renderer renderer = null;
  73. if (shape instanceof Path2D) {
  74. renderer = OpenPiscesPrismUtils.setupRenderer((Path2D) shape, stroke, xform, rclip);
  75. }
  76. if (renderer == null) {
  77. renderer = OpenPiscesPrismUtils.setupRenderer(shape, stroke, xform, rclip);
  78. }
  79. int outpix_xmin = renderer.getOutpixMinX();
  80. int outpix_ymin = renderer.getOutpixMinY();
  81. int outpix_xmax = renderer.getOutpixMaxX();
  82. int outpix_ymax = renderer.getOutpixMaxY();
  83. int w = outpix_xmax - outpix_xmin;
  84. int h = outpix_ymax - outpix_ymin;
  85. if (w <= 0 || h <= 0) {
  86. return emptyData;
  87. }
  88. Consumer consumer = savedConsumer;
  89. if (consumer == null || w * h > consumer.getAlphaLength()) {
  90. int csize = (w * h + 0xfff) & (~0xfff);
  91. savedConsumer = consumer = new Consumer(csize);
  92. if (PrismSettings.verbose) {
  93. System.out.println("new alphas");
  94. }
  95. }
  96. consumer.setBoundsNoClone(outpix_xmin, outpix_ymin, w, h);
  97. renderer.produceAlphas(consumer);
  98. return consumer.getMaskData();
  99. }
  100. private static class Consumer implements AlphaConsumer {
  101. static byte savedAlphaMap[];
  102. int x, y, width, height;
  103. byte alphas[];
  104. byte alphaMap[];
  105. ByteBuffer alphabuffer;
  106. MaskData maskdata = new MaskData();
  107. public Consumer(int alphalen) {
  108. this.alphas = new byte[alphalen];
  109. alphabuffer = ByteBuffer.wrap(alphas);
  110. }
  111. public void setBoundsNoClone(int x, int y, int w, int h) {
  112. this.x = x;
  113. this.y = y;
  114. this.width = w;
  115. this.height = h;
  116. maskdata.update(alphabuffer, x, y, w, h);
  117. }
  118. @Override
  119. public int getOriginX() {
  120. return x;
  121. }
  122. @Override
  123. public int getOriginY() {
  124. return y;
  125. }
  126. @Override
  127. public int getWidth() {
  128. return width;
  129. }
  130. @Override
  131. public int getHeight() {
  132. return height;
  133. }
  134. public byte[] getAlphasNoClone() {
  135. return alphas;
  136. }
  137. public int getAlphaLength() {
  138. return alphas.length;
  139. }
  140. public MaskData getMaskData() {
  141. return maskdata;
  142. }
  143. @Override
  144. public void setMaxAlpha(int maxalpha) {
  145. byte map[] = savedAlphaMap;
  146. if (map == null || map.length != maxalpha+1) {
  147. map = new byte[maxalpha+1];
  148. for (int i = 0; i <= maxalpha; i++) {
  149. map[i] = (byte) ((i*255 + maxalpha/2)/maxalpha);
  150. }
  151. savedAlphaMap = map;
  152. }
  153. this.alphaMap = map;
  154. }
  155. @Override
  156. public void setAndClearRelativeAlphas(int[] alphaRow, int pix_y,
  157. int pix_from, int pix_to)
  158. {
  159. // System.out.println("setting row "+(pix_y - y)+
  160. // " out of "+width+" x "+height);
  161. int w = width;
  162. int off = (pix_y - y) * w;
  163. byte out[] = this.alphas;
  164. byte map[] = this.alphaMap;
  165. int a = 0;
  166. for (int i = 0; i < w; i++) {
  167. a += alphaRow[i];
  168. alphaRow[i] = 0;
  169. out[off+i] = map[a];
  170. }
  171. }
  172. public void setAndClearRelativeAlphas2(int[] alphaDeltas, int pix_y,
  173. int pix_from, int pix_to)
  174. {
  175. if (pix_to >= pix_from) {
  176. byte out[] = this.alphas;
  177. byte map[] = this.alphaMap;
  178. int from = pix_from - x;
  179. int to = pix_to - x;
  180. int w = width;
  181. int off = (pix_y - y) * w;
  182. int i = 0;
  183. while (i < from) {
  184. out[off+i] = 0;
  185. i++;
  186. }
  187. int curAlpha = 0;
  188. while (i <= to) {
  189. curAlpha += alphaDeltas[i];
  190. alphaDeltas[i] = 0;
  191. byte a = map[curAlpha];
  192. out[off+i] = a;
  193. i++;
  194. }
  195. alphaDeltas[i] = 0;
  196. while (i < w) {
  197. out[off+i] = 0;
  198. i++;
  199. }
  200. } else {
  201. java.util.Arrays.fill(alphaDeltas, 0);
  202. }
  203. }
  204. }
  205. }