History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/java2d (352 of 18352 files). Show all

Unified · Split

352 files
  1. java/pkg/sun/java2d/DefaultDisposerRecord.class +0 −0
  2. java/pkg/sun/java2d/DefaultDisposerRecord.java +56 −0
  3. java/pkg/sun/java2d/DestSurfaceProvider.class +0 −0
  4. java/pkg/sun/java2d/DestSurfaceProvider.java +41 −0
  5. java/pkg/sun/java2d/Disposer$1.class +0 −0
  6. java/pkg/sun/java2d/Disposer$PollDisposable.class +0 −0
  7. java/pkg/sun/java2d/Disposer.class +0 −0
  8. java/pkg/sun/java2d/Disposer.java +262 −0
  9. java/pkg/sun/java2d/DisposerRecord.class +0 −0
  10. java/pkg/sun/java2d/DisposerRecord.java +34 −0
  11. java/pkg/sun/java2d/DisposerTarget.class +0 −0
  12. java/pkg/sun/java2d/DisposerTarget.java +38 −0
  13. java/pkg/sun/java2d/FontSupport.class +0 −0
  14. java/pkg/sun/java2d/FontSupport.java +39 −0
  15. java/pkg/sun/java2d/HeadlessGraphicsEnvironment.class +0 −0
  16. java/pkg/sun/java2d/HeadlessGraphicsEnvironment.java +103 −0
  17. java/pkg/sun/java2d/InvalidPipeException.class +0 −0
  18. java/pkg/sun/java2d/InvalidPipeException.java +55 −0
  19. java/pkg/sun/java2d/NullSurfaceData.class +0 −0
  20. java/pkg/sun/java2d/NullSurfaceData.java +159 −0
  21. java/pkg/sun/java2d/Spans.java +393 −0
  22. java/pkg/sun/java2d/StateTrackable$State.class +0 −0
  23. java/pkg/sun/java2d/StateTrackable.class +0 −0
  24. java/pkg/sun/java2d/StateTrackable.java +256 −0
  25. java/pkg/sun/java2d/StateTrackableDelegate$1.class +0 −0
  26. java/pkg/sun/java2d/StateTrackableDelegate$2.class +0 −0
  27. java/pkg/sun/java2d/StateTrackableDelegate.class +0 −0
  28. java/pkg/sun/java2d/StateTrackableDelegate.java +256 −0
  29. java/pkg/sun/java2d/StateTracker$1.class +0 −0
  30. java/pkg/sun/java2d/StateTracker$2.class +0 −0
  31. java/pkg/sun/java2d/StateTracker.class +0 −0
  32. java/pkg/sun/java2d/StateTracker.java +104 −0
  33. java/pkg/sun/java2d/SunCompositeContext.class +0 −0
  34. java/pkg/sun/java2d/SunCompositeContext.java +129 −0
  35. java/pkg/sun/java2d/SunGraphics2D.class +0 −0
  36. java/pkg/sun/java2d/SunGraphics2D.java +3310 −0
  37. java/pkg/sun/java2d/SunGraphicsEnvironment$1.class +0 −0
  38. java/pkg/sun/java2d/SunGraphicsEnvironment.class +0 −0
  39. java/pkg/sun/java2d/SunGraphicsEnvironment.java +337 −0
  40. java/pkg/sun/java2d/Surface.class +0 −0
  41. java/pkg/sun/java2d/Surface.java +34 −0
  42. java/pkg/sun/java2d/SurfaceData$PixelToPgramLoopConverter.class +0 −0
  43. java/pkg/sun/java2d/SurfaceData$PixelToShapeLoopConverter.class +0 −0
  44. java/pkg/sun/java2d/SurfaceData.class +0 −0
  45. java/pkg/sun/java2d/SurfaceData.java +1060 −0
  46. java/pkg/sun/java2d/SurfaceDataProxy$1.class +0 −0
  47. java/pkg/sun/java2d/SurfaceDataProxy$CountdownTracker.class +0 −0
  48. java/pkg/sun/java2d/SurfaceDataProxy.class +0 −0
  49. java/pkg/sun/java2d/SurfaceDataProxy.java +528 −0
  50. java/pkg/sun/java2d/SurfaceManagerFactory.class +0 −0
  51. java/pkg/sun/java2d/SurfaceManagerFactory.java +91 −0
  52. java/pkg/sun/java2d/cmm/CMSManager$1.class +0 −0
  53. java/pkg/sun/java2d/cmm/CMSManager$CMMTracer.class +0 −0
  54. java/pkg/sun/java2d/cmm/CMSManager.class +0 −0
  55. java/pkg/sun/java2d/cmm/CMSManager.java +170 −0
  56. java/pkg/sun/java2d/cmm/ColorTransform.class +0 −0
  57. java/pkg/sun/java2d/cmm/ColorTransform.java +53 −0
  58. java/pkg/sun/java2d/cmm/PCMM.class +0 −0
  59. java/pkg/sun/java2d/cmm/PCMM.java +48 −0
  60. java/pkg/sun/java2d/cmm/ProfileActivator.class +0 −0
  61. java/pkg/sun/java2d/cmm/ProfileActivator.java +41 −0
  62. java/pkg/sun/java2d/cmm/ProfileDeferralInfo.class +0 −0
  63. java/pkg/sun/java2d/cmm/ProfileDeferralInfo.java +61 −0
  64. java/pkg/sun/java2d/cmm/ProfileDeferralMgr.class +0 −0
  65. java/pkg/sun/java2d/cmm/ProfileDeferralMgr.java +119 −0
  66. java/pkg/sun/java2d/cmm/lcms/LCMS.java +104 −0
  67. java/pkg/sun/java2d/cmm/lcms/LCMSImageLayout.java +235 −0
  68. java/pkg/sun/java2d/cmm/lcms/LCMSTransform.java +609 −0
  69. java/pkg/sun/java2d/cmm/lcms/META-INF/mkfile +6 −0
  70. java/pkg/sun/java2d/cmm/lcms/META-INF/services/mkfile +2 −0
  71. java/pkg/sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.PCMM +2 −0
  72. java/pkg/sun/java2d/cmm/lcms/mkfile +14 −0
  73. java/pkg/sun/java2d/cmm/mkfile +17 −0
  74. java/pkg/sun/java2d/loops/Blit$AnyBlit.class +0 −0
  75. java/pkg/sun/java2d/loops/Blit$GeneralMaskBlit.class +0 −0
  76. java/pkg/sun/java2d/loops/Blit$GeneralXorBlit.class +0 −0
  77. java/pkg/sun/java2d/loops/Blit$TraceBlit.class +0 −0
  78. java/pkg/sun/java2d/loops/Blit.class +0 −0
  79. java/pkg/sun/java2d/loops/Blit.java +332 −0
  80. java/pkg/sun/java2d/loops/BlitBg$General.class +0 −0
  81. java/pkg/sun/java2d/loops/BlitBg$TraceBlitBg.class +0 −0
  82. java/pkg/sun/java2d/loops/BlitBg.class +0 −0
  83. java/pkg/sun/java2d/loops/BlitBg.java +217 −0
  84. java/pkg/sun/java2d/loops/CompositeType.class +0 −0
  85. java/pkg/sun/java2d/loops/CompositeType.java +295 −0
  86. java/pkg/sun/java2d/loops/CustomComponent.class +0 −0
  87. java/pkg/sun/java2d/loops/CustomComponent.java +329 −0
  88. java/pkg/sun/java2d/loops/DrawGlyphList$General.class +0 −0
  89. java/pkg/sun/java2d/loops/DrawGlyphList$TraceDrawGlyphList.class +0 −0
  90. java/pkg/sun/java2d/loops/DrawGlyphList.class +0 −0
  91. java/pkg/sun/java2d/loops/DrawGlyphList.java +161 −0
  92. java/pkg/sun/java2d/loops/DrawGlyphListAA$General.class +0 −0
  93. java/pkg/sun/java2d/loops/DrawGlyphListAA$TraceDrawGlyphListAA.class +0 −0
  94. java/pkg/sun/java2d/loops/DrawGlyphListAA.class +0 −0
  95. java/pkg/sun/java2d/loops/DrawGlyphListAA.java +159 −0
  96. java/pkg/sun/java2d/loops/DrawGlyphListLCD$TraceDrawGlyphListLCD.class +0 −0
  97. java/pkg/sun/java2d/loops/DrawGlyphListLCD.class +0 −0
  98. java/pkg/sun/java2d/loops/DrawGlyphListLCD.java +117 −0
  99. java/pkg/sun/java2d/loops/DrawLine$TraceDrawLine.class +0 −0
  100. java/pkg/sun/java2d/loops/DrawLine.class +0 −0
  101. java/pkg/sun/java2d/loops/DrawLine.java +114 −0
  102. java/pkg/sun/java2d/loops/DrawParallelogram$TraceDrawParallelogram.class +0 −0
  103. java/pkg/sun/java2d/loops/DrawParallelogram.class +0 −0
  104. java/pkg/sun/java2d/loops/DrawParallelogram.java +123 −0
  105. java/pkg/sun/java2d/loops/DrawPath$TraceDrawPath.class +0 −0
  106. java/pkg/sun/java2d/loops/DrawPath.class +0 −0
  107. java/pkg/sun/java2d/loops/DrawPath.java +114 −0
  108. java/pkg/sun/java2d/loops/DrawPolygons$TraceDrawPolygons.class +0 −0
  109. java/pkg/sun/java2d/loops/DrawPolygons.class +0 −0
  110. java/pkg/sun/java2d/loops/DrawPolygons.java +120 −0
  111. java/pkg/sun/java2d/loops/DrawRect$TraceDrawRect.class +0 −0
  112. java/pkg/sun/java2d/loops/DrawRect.class +0 −0
  113. java/pkg/sun/java2d/loops/DrawRect.java +115 −0
  114. java/pkg/sun/java2d/loops/FillParallelogram$TraceFillParallelogram.class +0 −0
  115. java/pkg/sun/java2d/loops/FillParallelogram.class +0 −0
  116. java/pkg/sun/java2d/loops/FillParallelogram.java +118 −0
  117. java/pkg/sun/java2d/loops/FillPath$TraceFillPath.class +0 −0
  118. java/pkg/sun/java2d/loops/FillPath.class +0 −0
  119. java/pkg/sun/java2d/loops/FillPath.java +114 −0
  120. java/pkg/sun/java2d/loops/FillRect$General.class +0 −0
  121. java/pkg/sun/java2d/loops/FillRect$TraceFillRect.class +0 −0
  122. java/pkg/sun/java2d/loops/FillRect.class +0 −0
  123. java/pkg/sun/java2d/loops/FillRect.java +135 −0
  124. java/pkg/sun/java2d/loops/FillSpans$TraceFillSpans.class +0 −0
  125. java/pkg/sun/java2d/loops/FillSpans.class +0 −0
  126. java/pkg/sun/java2d/loops/FillSpans.java +122 −0
  127. java/pkg/sun/java2d/loops/FontInfo.class +0 −0
  128. java/pkg/sun/java2d/loops/FontInfo.java +89 −0
  129. java/pkg/sun/java2d/loops/GeneralRenderer.class +0 −0
  130. java/pkg/sun/java2d/loops/GeneralRenderer.java +1125 −0
  131. java/pkg/sun/java2d/loops/GraphicsPrimitive$1.class +0 −0
  132. java/pkg/sun/java2d/loops/GraphicsPrimitive$GeneralBinaryOp.class +0 −0
  133. java/pkg/sun/java2d/loops/GraphicsPrimitive$GeneralUnaryOp.class +0 −0
  134. java/pkg/sun/java2d/loops/GraphicsPrimitive$TraceReporter$1.class +0 −0
  135. java/pkg/sun/java2d/loops/GraphicsPrimitive$TraceReporter.class +0 −0
  136. java/pkg/sun/java2d/loops/GraphicsPrimitive.class +0 −0
  137. java/pkg/sun/java2d/loops/GraphicsPrimitive.java +623 −0
  138. java/pkg/sun/java2d/loops/GraphicsPrimitiveMgr$1.class +0 −0
  139. java/pkg/sun/java2d/loops/GraphicsPrimitiveMgr$2.class +0 −0
  140. java/pkg/sun/java2d/loops/GraphicsPrimitiveMgr$PrimitiveSpec.class +0 −0
  141. java/pkg/sun/java2d/loops/GraphicsPrimitiveMgr.class +0 −0
  142. java/pkg/sun/java2d/loops/GraphicsPrimitiveMgr.java +330 −0
  143. java/pkg/sun/java2d/loops/GraphicsPrimitiveProxy.class +0 −0
  144. java/pkg/sun/java2d/loops/GraphicsPrimitiveProxy.java +114 −0
  145. java/pkg/sun/java2d/loops/MaskBlit$General.class +0 −0
  146. java/pkg/sun/java2d/loops/MaskBlit$TraceMaskBlit.class +0 −0
  147. java/pkg/sun/java2d/loops/MaskBlit.class +0 −0
  148. java/pkg/sun/java2d/loops/MaskBlit.java +264 −0
  149. java/pkg/sun/java2d/loops/MaskFill$General.class +0 −0
  150. java/pkg/sun/java2d/loops/MaskFill$TraceMaskFill.class +0 −0
  151. java/pkg/sun/java2d/loops/MaskFill.class +0 −0
  152. java/pkg/sun/java2d/loops/MaskFill.java +273 −0
  153. java/pkg/sun/java2d/loops/OpaqueCopyAnyToArgb.class +0 −0
  154. java/pkg/sun/java2d/loops/OpaqueCopyArgbToAny.class +0 −0
  155. java/pkg/sun/java2d/loops/PixelWriter.class +0 −0
  156. java/pkg/sun/java2d/loops/PixelWriterDrawHandler.class +0 −0
  157. java/pkg/sun/java2d/loops/ProcessPath$1.class +0 −0
  158. java/pkg/sun/java2d/loops/ProcessPath$ActiveEdgeList.class +0 −0
  159. java/pkg/sun/java2d/loops/ProcessPath$DrawHandler.class +0 −0
  160. java/pkg/sun/java2d/loops/ProcessPath$DrawProcessHandler.class +0 −0
  161. java/pkg/sun/java2d/loops/ProcessPath$Edge.class +0 −0
  162. java/pkg/sun/java2d/loops/ProcessPath$EndSubPathHandler.class +0 −0
  163. java/pkg/sun/java2d/loops/ProcessPath$FillData.class +0 −0
  164. java/pkg/sun/java2d/loops/ProcessPath$FillProcessHandler.class +0 −0
  165. java/pkg/sun/java2d/loops/ProcessPath$Point.class +0 −0
  166. java/pkg/sun/java2d/loops/ProcessPath$ProcessHandler.class +0 −0
  167. java/pkg/sun/java2d/loops/ProcessPath.class +0 −0
  168. java/pkg/sun/java2d/loops/ProcessPath.java +2128 −0
  169. java/pkg/sun/java2d/loops/RenderCache$Entry.class +0 −0
  170. java/pkg/sun/java2d/loops/RenderCache.class +0 −0
  171. java/pkg/sun/java2d/loops/RenderCache.java +103 −0
  172. java/pkg/sun/java2d/loops/RenderLoops.class +0 −0
  173. java/pkg/sun/java2d/loops/RenderLoops.java +55 −0
  174. java/pkg/sun/java2d/loops/ScaledBlit$TraceScaledBlit.class +0 −0
  175. java/pkg/sun/java2d/loops/ScaledBlit.class +0 −0
  176. java/pkg/sun/java2d/loops/ScaledBlit.java +156 −0
  177. java/pkg/sun/java2d/loops/SetDrawLineANY.class +0 −0
  178. java/pkg/sun/java2d/loops/SetDrawPathANY.class +0 −0
  179. java/pkg/sun/java2d/loops/SetDrawPolygonsANY.class +0 −0
  180. java/pkg/sun/java2d/loops/SetDrawRectANY.class +0 −0
  181. java/pkg/sun/java2d/loops/SetFillPathANY.class +0 −0
  182. java/pkg/sun/java2d/loops/SetFillRectANY.class +0 −0
  183. java/pkg/sun/java2d/loops/SetFillSpansANY.class +0 −0
  184. java/pkg/sun/java2d/loops/SolidPixelWriter.class +0 −0
  185. java/pkg/sun/java2d/loops/SurfaceType.class +0 −0
  186. java/pkg/sun/java2d/loops/SurfaceType.java +460 −0
  187. java/pkg/sun/java2d/loops/TransformBlit.java +157 −0
  188. java/pkg/sun/java2d/loops/TransformHelper$TraceTransformHelper.class +0 −0
  189. java/pkg/sun/java2d/loops/TransformHelper.class +0 −0
  190. java/pkg/sun/java2d/loops/TransformHelper.java +140 −0
  191. java/pkg/sun/java2d/loops/XORComposite.class +0 −0
  192. java/pkg/sun/java2d/loops/XORComposite.java +72 −0
  193. java/pkg/sun/java2d/loops/XorCopyArgbToAny.class +0 −0
  194. java/pkg/sun/java2d/loops/XorDrawGlyphListAAANY.class +0 −0
  195. java/pkg/sun/java2d/loops/XorDrawGlyphListANY.class +0 −0
  196. java/pkg/sun/java2d/loops/XorDrawLineANY.class +0 −0
  197. java/pkg/sun/java2d/loops/XorDrawPathANY.class +0 −0
  198. java/pkg/sun/java2d/loops/XorDrawPolygonsANY.class +0 −0
  199. java/pkg/sun/java2d/loops/XorDrawRectANY.class +0 −0
  200. java/pkg/sun/java2d/loops/XorFillPathANY.class +0 −0
  201. java/pkg/sun/java2d/loops/XorFillRectANY.class +0 −0
  202. java/pkg/sun/java2d/loops/XorFillSpansANY.class +0 −0
  203. java/pkg/sun/java2d/loops/XorPixelWriter$ByteData.class +0 −0
  204. java/pkg/sun/java2d/loops/XorPixelWriter$DoubleData.class +0 −0
  205. java/pkg/sun/java2d/loops/XorPixelWriter$FloatData.class +0 −0
  206. java/pkg/sun/java2d/loops/XorPixelWriter$IntData.class +0 −0
  207. java/pkg/sun/java2d/loops/XorPixelWriter$ShortData.class +0 −0
  208. java/pkg/sun/java2d/loops/XorPixelWriter.class +0 −0
  209. java/pkg/sun/java2d/loops/mkfile +38 −0
  210. java/pkg/sun/java2d/mkfile +35 −0
  211. java/pkg/sun/java2d/opengl/OGLBlitLoops.java +762 −0
  212. java/pkg/sun/java2d/opengl/OGLBufImgOps.java +115 −0
  213. java/pkg/sun/java2d/opengl/OGLContext.java +220 −0
  214. java/pkg/sun/java2d/opengl/OGLDrawImage.java +113 −0
  215. java/pkg/sun/java2d/opengl/OGLGraphicsConfig.java +44 −0
  216. java/pkg/sun/java2d/opengl/OGLMaskBlit.java +69 −0
  217. java/pkg/sun/java2d/opengl/OGLMaskFill.java +75 −0
  218. java/pkg/sun/java2d/opengl/OGLPaints.java +209 −0
  219. java/pkg/sun/java2d/opengl/OGLRenderQueue.java +239 −0
  220. java/pkg/sun/java2d/opengl/OGLRenderer.java +206 −0
  221. java/pkg/sun/java2d/opengl/OGLSurfaceData.java +653 −0
  222. java/pkg/sun/java2d/opengl/OGLSurfaceDataProxy.java +81 −0
  223. java/pkg/sun/java2d/opengl/OGLTextRenderer.java +71 −0
  224. java/pkg/sun/java2d/opengl/OGLUtilities.java +338 −0
  225. java/pkg/sun/java2d/opengl/mkfile +21 −0
  226. java/pkg/sun/java2d/pipe/AAShapePipe.class +0 −0
  227. java/pkg/sun/java2d/pipe/AAShapePipe.java +215 −0
  228. java/pkg/sun/java2d/pipe/AATextRenderer.class +0 −0
  229. java/pkg/sun/java2d/pipe/AATextRenderer.java +45 −0
  230. java/pkg/sun/java2d/pipe/AATileGenerator.class +0 −0
  231. java/pkg/sun/java2d/pipe/AATileGenerator.java +111 −0
  232. java/pkg/sun/java2d/pipe/AlphaColorPipe.class +0 −0
  233. java/pkg/sun/java2d/pipe/AlphaColorPipe.java +90 −0
  234. java/pkg/sun/java2d/pipe/AlphaPaintPipe$TileContext.class +0 −0
  235. java/pkg/sun/java2d/pipe/AlphaPaintPipe.class +0 −0
  236. java/pkg/sun/java2d/pipe/AlphaPaintPipe.java +206 −0
  237. java/pkg/sun/java2d/pipe/BufferedBufImgOps.java +393 −0
  238. java/pkg/sun/java2d/pipe/BufferedContext.class +0 −0
  239. java/pkg/sun/java2d/pipe/BufferedContext.java +470 −0
  240. java/pkg/sun/java2d/pipe/BufferedMaskBlit.java +163 −0
  241. java/pkg/sun/java2d/pipe/BufferedMaskFill.java +153 −0
  242. java/pkg/sun/java2d/pipe/BufferedOpCodes.class +0 −0
  243. java/pkg/sun/java2d/pipe/BufferedOpCodes.java +99 −0
  244. java/pkg/sun/java2d/pipe/BufferedPaints.class +0 −0
  245. java/pkg/sun/java2d/pipe/BufferedPaints.java +533 −0
  246. java/pkg/sun/java2d/pipe/BufferedRenderPipe$1.class +0 −0
  247. java/pkg/sun/java2d/pipe/BufferedRenderPipe$AAParallelogramPipe.class +0 −0
  248. java/pkg/sun/java2d/pipe/BufferedRenderPipe$BufferedDrawHandler.class +0 −0
  249. java/pkg/sun/java2d/pipe/BufferedRenderPipe.class +0 −0
  250. java/pkg/sun/java2d/pipe/BufferedRenderPipe.java +601 −0
  251. java/pkg/sun/java2d/pipe/BufferedTextPipe.java +168 −0
  252. java/pkg/sun/java2d/pipe/CompositePipe.class +0 −0
  253. java/pkg/sun/java2d/pipe/CompositePipe.java +50 −0
  254. java/pkg/sun/java2d/pipe/DrawImage.class +0 −0
  255. java/pkg/sun/java2d/pipe/DrawImage.java +1110 −0
  256. java/pkg/sun/java2d/pipe/DrawImagePipe.class +0 −0
  257. java/pkg/sun/java2d/pipe/DrawImagePipe.java +86 −0
  258. java/pkg/sun/java2d/pipe/GeneralCompositePipe$TileContext.class +0 −0
  259. java/pkg/sun/java2d/pipe/GeneralCompositePipe.class +0 −0
  260. java/pkg/sun/java2d/pipe/GeneralCompositePipe.java +154 −0
  261. java/pkg/sun/java2d/pipe/GlyphListLoopPipe.class +0 −0
  262. java/pkg/sun/java2d/pipe/GlyphListLoopPipe.java +60 −0
  263. java/pkg/sun/java2d/pipe/GlyphListPipe.class +0 −0
  264. java/pkg/sun/java2d/pipe/GlyphListPipe.java +147 −0
  265. java/pkg/sun/java2d/pipe/LCDTextRenderer.class +0 −0
  266. java/pkg/sun/java2d/pipe/LCDTextRenderer.java +44 −0
  267. java/pkg/sun/java2d/pipe/LoopBasedPipe.class +0 −0
  268. java/pkg/sun/java2d/pipe/LoopBasedPipe.java +37 −0
  269. java/pkg/sun/java2d/pipe/LoopPipe.class +0 −0
  270. java/pkg/sun/java2d/pipe/LoopPipe.java +378 −0
  271. java/pkg/sun/java2d/pipe/NullPipe.class +0 −0
  272. java/pkg/sun/java2d/pipe/NullPipe.java +155 −0
  273. java/pkg/sun/java2d/pipe/OutlineTextRenderer.class +0 −0
  274. java/pkg/sun/java2d/pipe/OutlineTextRenderer.java +145 −0
  275. java/pkg/sun/java2d/pipe/ParallelogramPipe.class +0 −0
  276. java/pkg/sun/java2d/pipe/ParallelogramPipe.java +76 −0
  277. java/pkg/sun/java2d/pipe/PixelDrawPipe.class +0 −0
  278. java/pkg/sun/java2d/pipe/PixelDrawPipe.java +67 −0
  279. java/pkg/sun/java2d/pipe/PixelFillPipe.class +0 −0
  280. java/pkg/sun/java2d/pipe/PixelFillPipe.java +61 −0
  281. java/pkg/sun/java2d/pipe/PixelToParallelogramConverter.class +0 −0
  282. java/pkg/sun/java2d/pipe/PixelToParallelogramConverter.java +429 −0
  283. java/pkg/sun/java2d/pipe/PixelToShapeConverter.class +0 −0
  284. java/pkg/sun/java2d/pipe/PixelToShapeConverter.java +133 −0
  285. java/pkg/sun/java2d/pipe/Region$ImmutableRegion.class +0 −0
  286. java/pkg/sun/java2d/pipe/Region.class +0 −0
  287. java/pkg/sun/java2d/pipe/Region.java +1255 −0
  288. java/pkg/sun/java2d/pipe/RegionClipSpanIterator.class +0 −0
  289. java/pkg/sun/java2d/pipe/RegionClipSpanIterator.java +392 −0
  290. java/pkg/sun/java2d/pipe/RegionIterator.class +0 −0
  291. java/pkg/sun/java2d/pipe/RegionIterator.java +101 −0
  292. java/pkg/sun/java2d/pipe/RegionSpanIterator.class +0 −0
  293. java/pkg/sun/java2d/pipe/RegionSpanIterator.java +210 −0
  294. java/pkg/sun/java2d/pipe/RenderBuffer.class +0 −0
  295. java/pkg/sun/java2d/pipe/RenderBuffer.java +294 −0
  296. java/pkg/sun/java2d/pipe/RenderQueue.class +0 −0
  297. java/pkg/sun/java2d/pipe/RenderQueue.java +223 −0
  298. java/pkg/sun/java2d/pipe/RenderingEngine$1.class +0 −0
  299. java/pkg/sun/java2d/pipe/RenderingEngine$Tracer.class +0 −0
  300. java/pkg/sun/java2d/pipe/RenderingEngine.class +0 −0
  301. java/pkg/sun/java2d/pipe/RenderingEngine.java +482 −0
  302. java/pkg/sun/java2d/pipe/ShapeDrawPipe.class +0 −0
  303. java/pkg/sun/java2d/pipe/ShapeDrawPipe.java +40 −0
  304. java/pkg/sun/java2d/pipe/ShapeSpanIterator.class +0 −0
  305. java/pkg/sun/java2d/pipe/ShapeSpanIterator.java +201 −0
  306. java/pkg/sun/java2d/pipe/SolidTextRenderer.class +0 −0
  307. java/pkg/sun/java2d/pipe/SolidTextRenderer.java +44 −0
  308. java/pkg/sun/java2d/pipe/SpanClipRenderer$SCRcontext.class +0 −0
  309. java/pkg/sun/java2d/pipe/SpanClipRenderer.class +0 −0
  310. java/pkg/sun/java2d/pipe/SpanClipRenderer.java +141 −0
  311. java/pkg/sun/java2d/pipe/SpanIterator.class +0 −0
  312. java/pkg/sun/java2d/pipe/SpanIterator.java +95 −0
  313. java/pkg/sun/java2d/pipe/SpanShapeRenderer$Composite.class +0 −0
  314. java/pkg/sun/java2d/pipe/SpanShapeRenderer$Simple.class +0 −0
  315. java/pkg/sun/java2d/pipe/SpanShapeRenderer.class +0 −0
  316. java/pkg/sun/java2d/pipe/SpanShapeRenderer.java +216 −0
  317. java/pkg/sun/java2d/pipe/TextPipe.class +0 −0
  318. java/pkg/sun/java2d/pipe/TextPipe.java +49 −0
  319. java/pkg/sun/java2d/pipe/TextRenderer.class +0 −0
  320. java/pkg/sun/java2d/pipe/TextRenderer.java +98 −0
  321. java/pkg/sun/java2d/pipe/ValidatePipe.class +0 −0
  322. java/pkg/sun/java2d/pipe/ValidatePipe.java +241 −0
  323. java/pkg/sun/java2d/pipe/hw/AccelDeviceEventListener.class +0 −0
  324. java/pkg/sun/java2d/pipe/hw/AccelDeviceEventListener.java +59 −0
  325. java/pkg/sun/java2d/pipe/hw/AccelDeviceEventNotifier.java +167 −0
  326. java/pkg/sun/java2d/pipe/hw/AccelGraphicsConfig.class +0 −0
  327. java/pkg/sun/java2d/pipe/hw/AccelGraphicsConfig.java +95 −0
  328. java/pkg/sun/java2d/pipe/hw/AccelSurface.class +0 −0
  329. java/pkg/sun/java2d/pipe/hw/AccelSurface.java +136 −0
  330. java/pkg/sun/java2d/pipe/hw/AccelTypedVolatileImage.java +74 −0
  331. java/pkg/sun/java2d/pipe/hw/BufferedContextProvider.class +0 −0
  332. java/pkg/sun/java2d/pipe/hw/BufferedContextProvider.java +45 −0
  333. java/pkg/sun/java2d/pipe/hw/ContextCapabilities.class +0 −0
  334. java/pkg/sun/java2d/pipe/hw/ContextCapabilities.java +128 −0
  335. java/pkg/sun/java2d/pipe/hw/ExtendedBufferCapabilities$VSyncType.class +0 −0
  336. java/pkg/sun/java2d/pipe/hw/ExtendedBufferCapabilities.class +0 −0
  337. java/pkg/sun/java2d/pipe/hw/ExtendedBufferCapabilities.java +154 −0
  338. java/pkg/sun/java2d/pipe/hw/mkfile +15 −0
  339. java/pkg/sun/java2d/pipe/mkfile +56 −0
  340. java/pkg/sun/java2d/pisces/Curve.java +290 −0
  341. java/pkg/sun/java2d/pisces/Dasher.java +575 −0
  342. java/pkg/sun/java2d/pisces/Helpers.java +458 −0
  343. java/pkg/sun/java2d/pisces/META-INF/mkfile +6 −0
  344. java/pkg/sun/java2d/pisces/META-INF/services/mkfile +2 −0
  345. java/pkg/sun/java2d/pisces/META-INF/services/sun.java2d.pipe.RenderingEngine +2 −0
  346. java/pkg/sun/java2d/pisces/PiscesCache.java +186 −0
  347. java/pkg/sun/java2d/pisces/PiscesRenderingEngine.java +656 −0
  348. java/pkg/sun/java2d/pisces/PiscesTileGenerator.java +252 −0
  349. java/pkg/sun/java2d/pisces/Renderer.java +571 −0
  350. java/pkg/sun/java2d/pisces/Stroker.java +1223 −0
  351. java/pkg/sun/java2d/pisces/TransformingPathConsumer2D.java +393 −0
  352. java/pkg/sun/java2d/pisces/mkfile +20 −0
java/pkg/sun/java2d/DefaultDisposerRecord.class+0−0

Binary file not shown.

java/pkg/sun/java2d/DefaultDisposerRecord.java+56−0
@@ -0,0 +1,56 @@
1+/*
2+ * Copyright (c) 2002, 2005, 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+
26+package sun.java2d;
27+
28+/**
29+ * This class is the default DisposerRecord implementation which
30+ * holds pointers to the native disposal method and the data to be disposed.
31+ */
32+public class DefaultDisposerRecord implements DisposerRecord {
33+ private long dataPointer;
34+ private long disposerMethodPointer;
35+
36+ public DefaultDisposerRecord(long disposerMethodPointer, long dataPointer) {
37+ this.disposerMethodPointer = disposerMethodPointer;
38+ this.dataPointer = dataPointer;
39+ }
40+
41+ public void dispose() {
42+ invokeNativeDispose(disposerMethodPointer,
43+ dataPointer);
44+ }
45+
46+ public long getDataPointer() {
47+ return dataPointer;
48+ }
49+
50+ public long getDisposerMethodPointer() {
51+ return disposerMethodPointer;
52+ }
53+
54+ public static native void invokeNativeDispose(long disposerMethodPointer,
55+ long dataPointer);
56+}
java/pkg/sun/java2d/DestSurfaceProvider.class+0−0

Binary file not shown.

java/pkg/sun/java2d/DestSurfaceProvider.java+41−0
@@ -0,0 +1,41 @@
1+/*
2+ * Copyright (c) 2007, 2008, 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+
26+package sun.java2d;
27+
28+import sun.java2d.pipe.hw.*;
29+
30+/**
31+ * Classes implementing this interface provide access to their
32+ * destination surfaces.
33+ */
34+public interface DestSurfaceProvider {
35+ /**
36+ * Returns a surface currently used as a destination surface for rendering.
37+ *
38+ * @return destination surface
39+ */
40+ public Surface getDestSurface();
41+}
java/pkg/sun/java2d/Disposer$1.class+0−0

Binary file not shown.

java/pkg/sun/java2d/Disposer$PollDisposable.class+0−0

Binary file not shown.

java/pkg/sun/java2d/Disposer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/Disposer.java+262−0
@@ -0,0 +1,262 @@
1+/*
2+ * Copyright (c) 2002, 2010, 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+
26+package sun.java2d;
27+
28+import java.lang.ref.Reference;
29+import java.lang.ref.ReferenceQueue;
30+import java.lang.ref.PhantomReference;
31+import java.lang.ref.WeakReference;
32+import java.util.ArrayList;
33+import java.util.Hashtable;
34+
35+/**
36+ * This class is used for registering and disposing the native
37+ * data associated with java objects.
38+ *
39+ * The object can register itself by calling one of the addRecord
40+ * methods and providing either the pointer to the native disposal
41+ * method or a descendant of the DisposerRecord class with overridden
42+ * dispose() method.
43+ *
44+ * When the object becomes unreachable, the dispose() method
45+ * of the associated DisposerRecord object will be called.
46+ *
47+ * @see DisposerRecord
48+ */
49+public class Disposer implements Runnable {
50+ private static final ReferenceQueue queue = new ReferenceQueue();
51+ private static final Hashtable records = new Hashtable();
52+
53+ private static Disposer disposerInstance;
54+ public static final int WEAK = 0;
55+ public static final int PHANTOM = 1;
56+ public static int refType = PHANTOM;
57+
58+ static {
59+ java.security.AccessController.doPrivileged(
60+ new sun.security.action.LoadLibraryAction("awt"));
61+ initIDs();
62+ String type = (String) java.security.AccessController.doPrivileged(
63+ new sun.security.action.GetPropertyAction("sun.java2d.reftype"));
64+ if (type != null) {
65+ if (type.equals("weak")) {
66+ refType = WEAK;
67+ System.err.println("Using WEAK refs");
68+ } else {
69+ refType = PHANTOM;
70+ System.err.println("Using PHANTOM refs");
71+ }
72+ }
73+ disposerInstance = new Disposer();
74+ java.security.AccessController.doPrivileged(
75+ new java.security.PrivilegedAction() {
76+ public Object run() {
77+ /* The thread must be a member of a thread group
78+ * which will not get GCed before VM exit.
79+ * Make its parent the top-level thread group.
80+ */
81+ ThreadGroup tg = Thread.currentThread().getThreadGroup();
82+ for (ThreadGroup tgn = tg;
83+ tgn != null;
84+ tg = tgn, tgn = tg.getParent());
85+ Thread t =
86+ new Thread(tg, disposerInstance, "Java2D Disposer");
87+ t.setContextClassLoader(null);
88+ t.setDaemon(true);
89+ t.setPriority(Thread.MAX_PRIORITY);
90+ t.start();
91+ return null;
92+ }
93+ }
94+ );
95+ }
96+
97+ /**
98+ * Registers the object and the native data for later disposal.
99+ * @param target Object to be registered
100+ * @param disposeMethod pointer to the native disposal method
101+ * @param pData pointer to the data to be passed to the
102+ * native disposal method
103+ */
104+ public static void addRecord(Object target,
105+ long disposeMethod, long pData)
106+ {
107+ disposerInstance.add(target,
108+ new DefaultDisposerRecord(disposeMethod, pData));
109+ }
110+
111+ /**
112+ * Registers the object and the native data for later disposal.
113+ * @param target Object to be registered
114+ * @param rec the associated DisposerRecord object
115+ * @see DisposerRecord
116+ */
117+ public static void addRecord(Object target, DisposerRecord rec) {
118+ disposerInstance.add(target, rec);
119+ }
120+
121+ /**
122+ * Performs the actual registration of the target object to be disposed.
123+ * @param target Object to be registered, or if target is an instance
124+ * of DisposerTarget, its associated disposer referent
125+ * will be the Object that is registered
126+ * @param rec the associated DisposerRecord object
127+ * @see DisposerRecord
128+ */
129+ synchronized void add(Object target, DisposerRecord rec) {
130+ if (target instanceof DisposerTarget) {
131+ target = ((DisposerTarget)target).getDisposerReferent();
132+ }
133+ java.lang.ref.Reference ref;
134+ if (refType == PHANTOM) {
135+ ref = new PhantomReference(target, queue);
136+ } else {
137+ ref = new WeakReference(target, queue);
138+ }
139+ records.put(ref, rec);
140+ }
141+
142+ public void run() {
143+ while (true) {
144+ try {
145+ Object obj = queue.remove();
146+ ((Reference)obj).clear();
147+ DisposerRecord rec = (DisposerRecord)records.remove(obj);
148+ rec.dispose();
149+ obj = null;
150+ rec = null;
151+ clearDeferredRecords();
152+ } catch (Exception e) {
153+ System.out.println("Exception while removing reference: " + e);
154+ e.printStackTrace();
155+ }
156+ }
157+ }
158+
159+ /*
160+ * This is a marker interface that, if implemented, means it
161+ * doesn't acquire any special locks, and is safe to
162+ * be disposed in the poll loop on whatever thread
163+ * which happens to be the Toolkit thread, is in use.
164+ */
165+ public static interface PollDisposable {
166+ };
167+
168+ private static ArrayList<DisposerRecord> deferredRecords = null;
169+
170+ private static void clearDeferredRecords() {
171+ if (deferredRecords == null || deferredRecords.isEmpty()) {
172+ return;
173+ }
174+ for (int i=0;i<deferredRecords.size(); i++) {
175+ try {
176+ DisposerRecord rec = deferredRecords.get(i);
177+ rec.dispose();
178+ } catch (Exception e) {
179+ System.out.println("Exception while disposing deferred rec.");
180+ e.printStackTrace();
181+ }
182+ }
183+ deferredRecords.clear();
184+ }
185+
186+ /*
187+ * Set to indicate the queue is presently being polled.
188+ */
189+ public static volatile boolean pollingQueue = false;
190+
191+ /*
192+ * The pollRemove() method is called back from a dispose method
193+ * that is running on the toolkit thread and wants to
194+ * dispose any pending refs that are safe to be disposed
195+ * on that thread.
196+ */
197+ public static void pollRemove() {
198+
199+ /* This should never be called recursively, so this check
200+ * is just a safeguard against the unexpected.
201+ */
202+ if (pollingQueue) {
203+ return;
204+ }
205+ Object obj;
206+ pollingQueue = true;
207+ int freed = 0;
208+ int deferred = 0;
209+ try {
210+ while ((obj = queue.poll()) != null
211+ && freed < 10000 && deferred < 100) {
212+ freed++;
213+ ((Reference)obj).clear();
214+ DisposerRecord rec = (DisposerRecord)records.remove(obj);
215+ if (rec instanceof PollDisposable) {
216+ rec.dispose();
217+ obj = null;
218+ rec = null;
219+ } else {
220+ if (rec == null) { // shouldn't happen, but just in case.
221+ continue;
222+ }
223+ deferred++;
224+ if (deferredRecords == null) {
225+ deferredRecords = new ArrayList<DisposerRecord>(5);
226+ }
227+ deferredRecords.add(rec);
228+ }
229+ }
230+ } catch (Exception e) {
231+ System.out.println("Exception while removing reference: " + e);
232+ e.printStackTrace();
233+ } finally {
234+ pollingQueue = false;
235+ }
236+ }
237+
238+ private static native void initIDs();
239+
240+ /*
241+ * This was added for use by the 2D font implementation to avoid creation
242+ * of an additional disposer thread.
243+ * WARNING: this thread class monitors a specific queue, so a reference
244+ * added here must have been created with this queue. Failure to do
245+ * so will clutter the records hashmap and no one will be cleaning up
246+ * the reference queue.
247+ */
248+ public static void addReference(Reference ref, DisposerRecord rec) {
249+ records.put(ref, rec);
250+ }
251+
252+ public static void addObjectRecord(Object obj, DisposerRecord rec) {
253+ records.put(new WeakReference(obj, queue) , rec);
254+ }
255+
256+ /* This is intended for use in conjunction with addReference(..)
257+ */
258+ public static ReferenceQueue getQueue() {
259+ return queue;
260+ }
261+
262+}
java/pkg/sun/java2d/DisposerRecord.class+0−0

Binary file not shown.

java/pkg/sun/java2d/DisposerRecord.java+34−0
@@ -0,0 +1,34 @@
1+/*
2+ * Copyright (c) 2002, 2005, 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+
26+package sun.java2d;
27+
28+/**
29+ * This class is used to hold the resource to be
30+ * disposed.
31+ */
32+public interface DisposerRecord {
33+ public void dispose();
34+}
java/pkg/sun/java2d/DisposerTarget.class+0−0

Binary file not shown.

java/pkg/sun/java2d/DisposerTarget.java+38−0
@@ -0,0 +1,38 @@
1+/*
2+ * Copyright (c) 2002, 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+
26+package sun.java2d;
27+
28+/**
29+ * This is an interface which should be implemented by
30+ * the classes which use Disposer.
31+ */
32+public interface DisposerTarget {
33+ /**
34+ * Returns an object which will be
35+ * used as the referent in the ReferenceQueue
36+ */
37+ public Object getDisposerReferent();
38+}
java/pkg/sun/java2d/FontSupport.class+0−0

Binary file not shown.

java/pkg/sun/java2d/FontSupport.java+39−0
@@ -0,0 +1,39 @@
1+/*
2+ * Copyright (c) 2000, 2003, 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+
26+package sun.java2d;
27+
28+import sun.awt.FontConfiguration;
29+
30+/**
31+ * Font support for graphics environment
32+ */
33+public interface FontSupport {
34+
35+ /**
36+ * Returns the current font configuration.
37+ */
38+ public FontConfiguration getFontConfiguration();
39+}
java/pkg/sun/java2d/HeadlessGraphicsEnvironment.class+0−0

Binary file not shown.

java/pkg/sun/java2d/HeadlessGraphicsEnvironment.java+103−0
@@ -0,0 +1,103 @@
1+/*
2+ * Copyright (c) 2000, 2010, 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+
26+package sun.java2d;
27+
28+import java.awt.GraphicsEnvironment;
29+import java.awt.GraphicsDevice;
30+import java.awt.Graphics2D;
31+import java.awt.HeadlessException;
32+import java.awt.image.BufferedImage;
33+import java.awt.Font;
34+import java.text.AttributedCharacterIterator;
35+import java.awt.print.PrinterJob;
36+import java.util.Map;
37+import java.util.Hashtable;
38+import java.util.Locale;
39+import java.util.Vector;
40+import java.util.StringTokenizer;
41+import java.util.ResourceBundle;
42+import java.util.MissingResourceException;
43+import java.io.IOException;
44+import java.io.FilenameFilter;
45+import java.io.File;
46+import java.util.NoSuchElementException;
47+import sun.awt.FontConfiguration;
48+import java.util.TreeMap;
49+import java.util.Set;
50+import java.awt.font.TextAttribute;
51+import java.io.InputStream;
52+import java.io.FileInputStream;
53+import java.io.BufferedInputStream;
54+import java.util.Properties;
55+import java.awt.Point;
56+import java.awt.Rectangle;
57+
58+/**
59+ * Headless decorator implementation of a SunGraphicsEnvironment
60+ */
61+
62+public class HeadlessGraphicsEnvironment extends GraphicsEnvironment {
63+
64+ private GraphicsEnvironment ge;
65+
66+ public HeadlessGraphicsEnvironment(GraphicsEnvironment ge) {
67+ this.ge = ge;
68+ }
69+
70+ public GraphicsDevice[] getScreenDevices()
71+ throws HeadlessException {
72+ throw new HeadlessException();
73+ }
74+
75+ public GraphicsDevice getDefaultScreenDevice()
76+ throws HeadlessException {
77+ throw new HeadlessException();
78+ }
79+
80+ public Point getCenterPoint() throws HeadlessException {
81+ throw new HeadlessException();
82+ }
83+
84+ public Rectangle getMaximumWindowBounds() throws HeadlessException {
85+ throw new HeadlessException();
86+ }
87+
88+ public Graphics2D createGraphics(BufferedImage img) {
89+ return ge.createGraphics(img); }
90+
91+ public Font[] getAllFonts() { return ge.getAllFonts(); }
92+
93+ public String[] getAvailableFontFamilyNames() {
94+ return ge.getAvailableFontFamilyNames(); }
95+
96+ public String[] getAvailableFontFamilyNames(Locale l) {
97+ return ge.getAvailableFontFamilyNames(l); }
98+
99+ /* Used by FontManager : internal API */
100+ public GraphicsEnvironment getSunGraphicsEnvironment() {
101+ return ge;
102+ }
103+}
java/pkg/sun/java2d/InvalidPipeException.class+0−0

Binary file not shown.

java/pkg/sun/java2d/InvalidPipeException.java+55−0
@@ -0,0 +1,55 @@
1+/*
2+ * Copyright (c) 1999, 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+
26+package sun.java2d;
27+
28+/**
29+ * Signals that some part of a graphics pipeline is not in an appropriate
30+ * state for the requested operation. The most likely cause of this is
31+ * an asynchronous change to the configuration of the destination surface
32+ * since the current set of rendering loops was chosen. Other potential
33+ * causes are the appearance or disappearance of overlapping opaque
34+ * windows which toggle the need to use platform graphics or direct
35+ * graphics access.
36+ */
37+public class InvalidPipeException extends IllegalStateException {
38+ /**
39+ * Constructs an InvalidPipeException with no detail message.
40+ * A detail message is a String that describes this particular exception.
41+ */
42+ public InvalidPipeException() {
43+ super();
44+ }
45+
46+ /**
47+ * Constructs an InvalidPipeException with the specified detail
48+ * message. A detail message is a String that describes this particular
49+ * exception.
50+ * @param s the String that contains a detailed message
51+ */
52+ public InvalidPipeException(String s) {
53+ super(s);
54+ }
55+}
java/pkg/sun/java2d/NullSurfaceData.class+0−0

Binary file not shown.

java/pkg/sun/java2d/NullSurfaceData.java+159−0
@@ -0,0 +1,159 @@
1+/*
2+ * Copyright (c) 2002, 2007, 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+
26+package sun.java2d;
27+
28+import java.awt.Rectangle;
29+import java.awt.image.Raster;
30+import java.awt.image.ColorModel;
31+import java.awt.GraphicsConfiguration;
32+
33+import sun.java2d.StateTrackable.State;
34+import sun.java2d.loops.SurfaceType;
35+import sun.java2d.pipe.NullPipe;
36+
37+/**
38+ * This class provides an empty implementation of the SurfaceData
39+ * abstract superclass. All operations on it translate into NOP
40+ * or harmless operations.
41+ */
42+public class NullSurfaceData extends SurfaceData {
43+ public static final SurfaceData theInstance = new NullSurfaceData();
44+
45+ private NullSurfaceData() {
46+ super(State.IMMUTABLE, SurfaceType.Any, ColorModel.getRGBdefault());
47+ }
48+
49+ /**
50+ * Sets this SurfaceData object to the invalid state. All Graphics
51+ * objects must get a new SurfaceData object via the refresh method
52+ * and revalidate their pipelines before continuing.
53+ */
54+ public void invalidate() {
55+ }
56+
57+ /**
58+ * Return a new SurfaceData object that represents the current state
59+ * of the destination that this SurfaceData object describes.
60+ * This method is typically called when the SurfaceData is invalidated.
61+ */
62+ public SurfaceData getReplacement() {
63+ return this;
64+ }
65+
66+ private final static NullPipe nullpipe = new NullPipe();
67+
68+ public void validatePipe(SunGraphics2D sg2d) {
69+ sg2d.drawpipe = nullpipe;
70+ sg2d.fillpipe = nullpipe;
71+ sg2d.shapepipe = nullpipe;
72+ sg2d.textpipe = nullpipe;
73+ sg2d.imagepipe = nullpipe;
74+ }
75+
76+ public GraphicsConfiguration getDeviceConfiguration() {
77+ return null;
78+ }
79+
80+ /**
81+ * Return a readable Raster which contains the pixels for the
82+ * specified rectangular region of the destination surface.
83+ * The coordinate origin of the returned Raster is the same as
84+ * the device space origin of the destination surface.
85+ * In some cases the returned Raster might also be writeable.
86+ * In most cases, the returned Raster might contain more pixels
87+ * than requested.
88+ *
89+ * @see useTightBBoxes
90+ */
91+ public Raster getRaster(int x, int y, int w, int h) {
92+ throw new InvalidPipeException("should be NOP");
93+ }
94+
95+ /**
96+ * Does the pixel accessibility of the destination surface
97+ * suggest that rendering algorithms might want to take
98+ * extra time to calculate a more accurate bounding box for
99+ * the operation being performed?
100+ * The typical case when this will be true is when a copy of
101+ * the pixels has to be made when doing a getRaster. The
102+ * fewer pixels copied, the faster the operation will go.
103+ *
104+ * @see getRaster
105+ */
106+ public boolean useTightBBoxes() {
107+ return false;
108+ }
109+
110+ /**
111+ * Returns the pixel data for the specified Argb value packed
112+ * into an integer for easy storage and conveyance.
113+ */
114+ public int pixelFor(int rgb) {
115+ return rgb;
116+ }
117+
118+ /**
119+ * Returns the Argb representation for the specified integer value
120+ * which is packed in the format of the associated ColorModel.
121+ */
122+ public int rgbFor(int pixel) {
123+ return pixel;
124+ }
125+
126+ /**
127+ * Returns the bounds of the destination surface.
128+ */
129+ public Rectangle getBounds() {
130+ return new Rectangle();
131+ }
132+
133+ /**
134+ * Performs Security Permissions checks to see if a Custom
135+ * Composite object should be allowed access to the pixels
136+ * of this surface.
137+ */
138+ protected void checkCustomComposite() {
139+ return;
140+ }
141+
142+ /**
143+ * Performs a copyarea within this surface. Returns
144+ * false if there is no algorithm to perform the copyarea
145+ * given the current settings of the SunGraphics2D.
146+ */
147+ public boolean copyArea(SunGraphics2D sg2d,
148+ int x, int y, int w, int h, int dx, int dy)
149+ {
150+ return true;
151+ }
152+
153+ /**
154+ * Returns destination Image associated with this SurfaceData (null)
155+ */
156+ public Object getDestination() {
157+ return null;
158+ }
159+}
java/pkg/sun/java2d/Spans.java+393−0
@@ -0,0 +1,393 @@
1+/*
2+ * Copyright (c) 1998, 2000, 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+
26+package sun.java2d;
27+
28+import java.util.Comparator;
29+import java.util.Collections;
30+import java.util.Iterator;
31+import java.util.List;
32+import java.util.Vector;
33+
34+/**
35+ * Maintains a list of half-open intervals, called Spans.
36+ * A Span can be tested against the list of Spans
37+ * for intersection.
38+ */
39+public class Spans {
40+
41+ /**
42+ * This class will sort and collapse its span
43+ * entries after this many span additions via
44+ * the <code>add</code> method.
45+ */
46+ private static final int kMaxAddsSinceSort = 256;
47+
48+ /**
49+ * Holds a list of individual
50+ * Span instances.
51+ */
52+ private List mSpans = new Vector(kMaxAddsSinceSort);
53+
54+ /**
55+ * The number of <code>Span</code>
56+ * instances that have been added
57+ * to this object without a sort
58+ * and collapse taking place.
59+ */
60+ private int mAddsSinceSort = 0;
61+
62+ public Spans() {
63+
64+ }
65+
66+ /**
67+ * Add a span covering the half open interval
68+ * including <code>start</code> up to
69+ * but not including <code>end</code>.
70+ */
71+ public void add(float start, float end) {
72+
73+ if (mSpans != null) {
74+ mSpans.add(new Span(start, end));
75+
76+ if (++mAddsSinceSort >= kMaxAddsSinceSort) {
77+ sortAndCollapse();
78+ }
79+ }
80+ }
81+
82+ /**
83+ * Add a span which covers the entire range.
84+ * This call is logically equivalent to
85+ * <code>add(Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY)</code>
86+ * The result of making this call is that
87+ * all future <code>add</code> calls are ignored
88+ * and the <code>intersects</code> method always
89+ * returns true.
90+ */
91+ public void addInfinite() {
92+ mSpans = null;
93+ }
94+
95+ /**
96+ * Returns true if the span defined by the half-open
97+ * interval from <code>start</code> up to,
98+ * but not including, <code>end</code> intersects
99+ * any of the spans defined by this instance.
100+ */
101+ public boolean intersects(float start, float end) {
102+ boolean doesIntersect;
103+
104+ if (mSpans != null) {
105+
106+ /* If we have added any spans since we last
107+ * sorted and collapsed our list of spans
108+ * then we need to resort and collapse.
109+ */
110+ if (mAddsSinceSort > 0) {
111+ sortAndCollapse();
112+ }
113+
114+ /* The SpanIntersection comparator considers
115+ * two spans equal if they intersect. If
116+ * the search finds a match then we have an
117+ * intersection.
118+ */
119+ int found = Collections.binarySearch(mSpans,
120+ new Span(start, end),
121+ SpanIntersection.instance);
122+
123+ doesIntersect = found >= 0;
124+
125+ /* The addInfinite() method has been invoked so
126+ * everything intersect this instance.
127+ */
128+ } else {
129+ doesIntersect = true;
130+ }
131+
132+ return doesIntersect;
133+ }
134+
135+ /**
136+ * Sort the spans in ascending order by their
137+ * start position. After the spans are sorted
138+ * collapse any spans that intersect into a
139+ * single span. The result is a sorted,
140+ * non-overlapping list of spans.
141+ */
142+ private void sortAndCollapse() {
143+
144+ Collections.sort(mSpans);
145+ mAddsSinceSort = 0;
146+
147+ Iterator iter = mSpans.iterator();
148+
149+ /* Have 'span' start at the first span in
150+ * the collection. The collection may be empty
151+ * so we're careful.
152+ */
153+ Span span = null;
154+ if (iter.hasNext()) {
155+ span = (Span) iter.next();
156+ }
157+
158+ /* Loop over the spans collapsing those that intersect
159+ * into a single span.
160+ */
161+ while (iter.hasNext()) {
162+
163+ Span nextSpan = (Span) iter.next();
164+
165+ /* The spans are in ascending start position
166+ * order and so the next span's starting point
167+ * is either in the span we are trying to grow
168+ * or it is beyond the first span and thus the
169+ * two spans do not intersect.
170+ *
171+ * span: <----------<
172+ * nextSpan: <------ (intersects)
173+ * nextSpan: <------ (doesn't intersect)
174+ *
175+ * If the spans intersect then we'll remove
176+ * nextSpan from the list. If nextSpan's
177+ * ending was beyond the first's then
178+ * we extend the first.
179+ *
180+ * span: <----------<
181+ * nextSpan: <-----< (don't change span)
182+ * nextSpan: <-----------< (grow span)
183+ */
184+
185+ if (span.subsume(nextSpan)) {
186+ iter.remove();
187+
188+ /* The next span did not intersect the current
189+ * span and so it can not be collapsed. Instead
190+ * it becomes the start of the next set of spans
191+ * to be collapsed.
192+ */
193+ } else {
194+ span = nextSpan;
195+ }
196+ }
197+ }
198+
199+ /*
200+ // For debugging.
201+
202+ private void printSpans() {
203+ System.out.println("----------");
204+ if (mSpans != null) {
205+ Iterator iter = mSpans.iterator();
206+ while (iter.hasNext()) {
207+ Span span = (Span) iter.next();
208+ System.out.println(span);
209+ }
210+ }
211+ System.out.println("----------");
212+
213+ }
214+ */
215+
216+ /**
217+ * Holds a single half-open interval.
218+ */
219+ static class Span implements Comparable {
220+
221+ /**
222+ * The span includes the starting point.
223+ */
224+ private float mStart;
225+
226+ /**
227+ * The span goes up to but does not include
228+ * the ending point.
229+ */
230+ private float mEnd;
231+
232+ /**
233+ * Create a half-open interval including
234+ * <code>start</code> but not including
235+ * <code>end</code>.
236+ */
237+ Span(float start, float end) {
238+ mStart = start;
239+ mEnd = end;
240+ }
241+
242+ /**
243+ * Return the start of the <code>Span</code>.
244+ * The start is considered part of the
245+ * half-open interval.
246+ */
247+ final float getStart() {
248+ return mStart;
249+ }
250+
251+ /**
252+ * Return the end of the <code>Span</code>.
253+ * The end is not considered part of the
254+ * half-open interval.
255+ */
256+ final float getEnd() {
257+ return mEnd;
258+ }
259+
260+ /**
261+ * Change the initial position of the
262+ * <code>Span</code>.
263+ */
264+ final void setStart(float start) {
265+ mStart = start;
266+ }
267+
268+ /**
269+ * Change the terminal position of the
270+ * <code>Span</code>.
271+ */
272+ final void setEnd(float end) {
273+ mEnd = end;
274+ }
275+
276+ /**
277+ * Attempt to alter this <code>Span</code>
278+ * to include <code>otherSpan</code> without
279+ * altering this span's starting position.
280+ * If <code>otherSpan</code> can be so consumed
281+ * by this <code>Span</code> then <code>true</code>
282+ * is returned.
283+ */
284+ boolean subsume(Span otherSpan) {
285+
286+ /* We can only subsume 'otherSpan' if
287+ * its starting position lies in our
288+ * interval.
289+ */
290+ boolean isSubsumed = contains(otherSpan.mStart);
291+
292+ /* If the other span's starting position
293+ * was in our interval and the other span
294+ * was longer than this span, then we need
295+ * to grow this span to cover the difference.
296+ */
297+ if (isSubsumed && otherSpan.mEnd > mEnd) {
298+ mEnd = otherSpan.mEnd;
299+ }
300+
301+ return isSubsumed;
302+ }
303+
304+ /**
305+ * Return true if the passed in position
306+ * lies in the half-open interval defined
307+ * by this <code>Span</code>.
308+ */
309+ boolean contains(float pos) {
310+ return mStart <= pos && pos < mEnd;
311+ }
312+
313+ /**
314+ * Rank spans according to their starting
315+ * position. The end position is ignored
316+ * in this ranking.
317+ */
318+ public int compareTo(Object o) {
319+ Span otherSpan = (Span) o;
320+ float otherStart = otherSpan.getStart();
321+ int result;
322+
323+ if (mStart < otherStart) {
324+ result = -1;
325+ } else if (mStart > otherStart) {
326+ result = 1;
327+ } else {
328+ result = 0;
329+ }
330+
331+ return result;
332+ }
333+
334+ public String toString() {
335+ return "Span: " + mStart + " to " + mEnd;
336+ }
337+
338+ }
339+
340+ /**
341+ * This class ranks a pair of <code>Span</code>
342+ * instances. If the instances intersect they
343+ * are deemed equal otherwise they are ranked
344+ * by their relative position. Use
345+ * <code>SpanIntersection.instance</code> to
346+ * get the single instance of this class.
347+ */
348+ static class SpanIntersection implements Comparator {
349+
350+ /**
351+ * This class is a Singleton and the following
352+ * is the single instance.
353+ */
354+ static final SpanIntersection instance =
355+ new SpanIntersection();
356+
357+ /**
358+ * Only this class can create instances of itself.
359+ */
360+ private SpanIntersection() {
361+
362+ }
363+
364+ public int compare(Object o1, Object o2) {
365+ int result;
366+ Span span1 = (Span) o1;
367+ Span span2 = (Span) o2;
368+
369+ /* Span 1 is entirely to the left of span2.
370+ * span1: <-----<
371+ * span2: <-----<
372+ */
373+ if (span1.getEnd() <= span2.getStart()) {
374+ result = -1;
375+
376+ /* Span 2 is entirely to the right of span2.
377+ * span1: <-----<
378+ * span2: <-----<
379+ */
380+ } else if (span1.getStart() >= span2.getEnd()) {
381+ result = 1;
382+
383+ /* Otherwise they intersect and we declare them equal.
384+ */
385+ } else {
386+ result = 0;
387+ }
388+
389+ return result;
390+ }
391+
392+ }
393+}
java/pkg/sun/java2d/StateTrackable$State.class+0−0

Binary file not shown.

java/pkg/sun/java2d/StateTrackable.class+0−0

Binary file not shown.

java/pkg/sun/java2d/StateTrackable.java+256−0
@@ -0,0 +1,256 @@
1+/*
2+ * Copyright (c) 2007, 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+
26+package sun.java2d;
27+
28+/**
29+ * This interface is implemented by classes which contain complex state
30+ * so that other objects can track whether or not their state has changed
31+ * since earlier interactions with the object.
32+ * <p>
33+ * The suggested usage pattern for code that manages some trackable data
34+ * is as follows:
35+ * <pre>
36+ * class Trackable implements StateTrackable {
37+ * TrackedInfo data;
38+ * State curState = STABLE;
39+ * StateTracker curTracker = null;
40+ * // Hypothetical method to return a static piece of our tracked data.
41+ * // Assume that Datum is either a copy of some piece of the tracked
42+ * // data or that it is itself immutable.
43+ * public Datum getSomeDatum(int key) {
44+ * // No need to modify the state for this type of "get" call.
45+ * return data.getDatum(key);
46+ * }
47+ * // Hypothetical method to return a raw reference to our tracked data.
48+ * public TrackedInfo getRawHandleToInfo() {
49+ * // Since we are returning a raw reference to our tracked
50+ * // data and since we can not track what the caller will
51+ * // do with that reference, we can no longer track the
52+ * // state of this data.
53+ * synchronized (this) {
54+ * // Note: modifying both curState and curTracker requires
55+ * // synchronization against the getStateTracker method.
56+ * curState = UNTRACKABLE;
57+ * curTracker = null;
58+ * }
59+ * return data;
60+ * }
61+ * // Hypothetical method to set a single piece of data to some
62+ * // new static value.
63+ * public void setSomeDatum(int key, Datum datum) {
64+ * data.setDatum(key, datum);
65+ * // We do not need to change state for this, we simply
66+ * // invalidate the outstanding StateTracker objects.
67+ * // Note: setting curTracker to null requires no synchronization.
68+ * curTracker = null;
69+ * }
70+ * // getStateTracker must be synchronized against any code that
71+ * // changes the State.
72+ * public synchronized StateTracker getStateTracker() {
73+ * StateTracker st = curTracker;
74+ * if (st == null) {
75+ * switch (curState) {
76+ * case IMMUTABLE: st = StateTracker.ALWAYS_CURRENT; break;
77+ * case STABLE: st = new Tracker(this); break;
78+ * case DYNAMIC: st = StateTracker.NEVER_CURRENT; break;
79+ * case UNTRACKABLE: st = StateTracker.NEVER_CURRENT; break;
80+ * }
81+ * curTracker = st;
82+ * }
83+ * return st;
84+ * }
85+ *
86+ * static class Tracker implements StateTracker {
87+ * Trackable theTrackable;
88+ * public Tracker(Trackable t) {
89+ * theTrackable = t;
90+ * }
91+ * public boolean isCurrent() {
92+ * return (theTrackable.curTracker == this);
93+ * }
94+ * }
95+ * }
96+ * </pre>
97+ * Note that the mechanism shown above for invalidating outstanding
98+ * StateTracker objects is not the most theoretically conservative
99+ * way to implement state tracking in a "set" method.
100+ * There is a small window of opportunity after the data has changed
101+ * before the outstanding StateTracker objects are invalidated and
102+ * where they will indicate that the data is still the same as when
103+ * they were instantiated.
104+ * While this is technically inaccurate, it is acceptable since the more
105+ * conservative approaches to state management are much more complex and
106+ * cost much more in terms of performance for a very small gain in
107+ * correctness.
108+ * For example:
109+ * <p>
110+ * The most conservative approach would be to synchronize all accesses
111+ * and all modifications to the data, including its State.
112+ * This would require synchronized blocks around some potentially large
113+ * bodies of code which would impact the multi-threaded scalability of
114+ * the implementation.
115+ * Further, if data is to be coordinated or transferred between two
116+ * trackable objects then both would need to be synchronized raising
117+ * the possibility of deadlock unless some strict rules of priority
118+ * for the locking of the objects were established and followed
119+ * religiously.
120+ * Either or both of these drawbacks makes such an implementation
121+ * infeasible.
122+ * <p>
123+ * A less conservative approach would be to change the state of the
124+ * trackable object to DYNAMIC during all modifications of the data
125+ * and then to change it back to STABLE after those modifications
126+ * are complete.
127+ * While this state transition more accurately reflects the temporary
128+ * loss of tracking during the modification phase, in reality the
129+ * time period of the modifications would be small in most cases
130+ * and the 2 changes of state would each require synchronization.
131+ * <p>
132+ * In comparison the act of setting the <code>curTracker</code>
133+ * reference to null in the usage pattern above effectively invalidates
134+ * all outstanding <code>Tracker</code> objects as soon as possible
135+ * after the change to the data and requires very little code and no
136+ * synchronization to implement.
137+ * <p>
138+ * In the end it is up to the implementor of a StateTrackable object
139+ * how fine the granularity of State updates should be managed based
140+ * on the frequency and atomicity of the modifications and the
141+ * consequences of returning an inaccurate State for a particularly
142+ * small window of opportunity.
143+ * Most implementations are likely to follow the liberal, but efficient
144+ * guidelines found in the usage pattern proposed above.
145+ *
146+ * @since 1.7
147+ */
148+public interface StateTrackable {
149+ /**
150+ * An enumeration describing the current state of a trackable
151+ * object.
152+ * These values describe how often the complex data contained
153+ * in a trackable object can be changed and whether or not it
154+ * makes sense to try to track the data in its current state.
155+ * @see StateTrackable#getState
156+ * @since 1.7
157+ */
158+ public enum State {
159+ /**
160+ * The complex data will never change again.
161+ * Information related to the current contents of the complex
162+ * data can be calculated and cached indefinitely with no
163+ * further checks to see if the information is stale.
164+ */
165+ IMMUTABLE,
166+
167+ /**
168+ * The complex data is currently stable, but could change at
169+ * some point in the future.
170+ * Information related to the current contents of the complex
171+ * data can be calculated and cached, but a StateTracker should
172+ * be used to verify the freshness of such precalculated data
173+ * before each future use.
174+ */
175+ STABLE,
176+
177+ /**
178+ * The complex data is currently in flux and is frequently
179+ * changing.
180+ * While information related to the current contents of the
181+ * complex data could be calculated and cached, there is a
182+ * reasonably high probability that the cached information
183+ * would be found to be out of date by the next time it is
184+ * used.
185+ * It may also be the case that the current contents are
186+ * temporarily untrackable, but that they may become trackable
187+ * again in the future.
188+ */
189+ DYNAMIC,
190+
191+ /**
192+ * The complex data can currently be changed by external
193+ * references and agents in a way that cannot be tracked.
194+ * If any information about the current contents of the complex
195+ * data were to be cached, there would be no way to determine
196+ * whether or not that cached information was out of date.
197+ */
198+ UNTRACKABLE,
199+ };
200+
201+ /**
202+ * Returns the general state of the complex data held by this
203+ * object.
204+ * This return value can be used to determine if it makes
205+ * strategic sense to try and cache information about the current
206+ * contents of this object.
207+ * The StateTracker returned from the getStateTracker() method
208+ * will further aid in determining when the data has been
209+ * changed so that the caches can be verified upon future uses.
210+ * @return the current state of trackability of the complex
211+ * data stored in this object.
212+ * @see #getStateTracker
213+ * @since 1.7
214+ */
215+ public State getState();
216+
217+ /**
218+ * Returns an object which can track future changes to the
219+ * complex data stored in this object.
220+ * If an external agent caches information about the complex
221+ * data of this object, it should first get a StateTracker
222+ * object from this method so that it can check if such
223+ * information is current upon future uses.
224+ * Note that a valid StateTracker will always be returned
225+ * regardless of the return value of getState(), but in some
226+ * cases the StateTracker may be a trivial implementation
227+ * which always returns the same value from its
228+ * {@link StateTracker#isCurrent isCurrent} method.
229+ * <ul>
230+ * <li>If the current state is {@link State#IMMUTABLE IMMUTABLE},
231+ * this StateTracker and any future StateTracker objects
232+ * returned from this method will always indicate that
233+ * the state has not changed.</li>
234+ * <li>If the current state is {@link State#UNTRACKABLE UNTRACKABLE},
235+ * this StateTracker and any future StateTracker objects
236+ * returned from this method will always indicate that
237+ * the state has changed.</li>
238+ * <li>If the current state is {@link State#DYNAMIC DYNAMIC},
239+ * this StateTracker may always indicate that the current
240+ * state has changed, but another StateTracker returned
241+ * from this method in the future when the state has changed
242+ * to {@link State#STABLE STABLE} will correctly track changes.</li>
243+ * <li>Otherwise the current state is {@link State#STABLE STABLE}
244+ * and this StateTracker will indicate whether or not the
245+ * data has changed since the time at which it was fetched
246+ * from the object.</li>
247+ * </ul>
248+ * @return an object implementing the StateTracker interface
249+ * that tracks whether changes have been made to the complex
250+ * contents of this object since it was returned.
251+ * @see State
252+ * @see #getState
253+ * @since 1.7
254+ */
255+ public StateTracker getStateTracker();
256+}
java/pkg/sun/java2d/StateTrackableDelegate$1.class+0−0

Binary file not shown.

java/pkg/sun/java2d/StateTrackableDelegate$2.class+0−0

Binary file not shown.

java/pkg/sun/java2d/StateTrackableDelegate.class+0−0

Binary file not shown.

java/pkg/sun/java2d/StateTrackableDelegate.java+256−0
@@ -0,0 +1,256 @@
1+/*
2+ * Copyright (c) 2007, 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+
26+package sun.java2d;
27+
28+import sun.java2d.StateTrackable.State;
29+import static sun.java2d.StateTrackable.State.*;
30+
31+/**
32+ * This class provides a basic pre-packaged implementation of the
33+ * complete {@link StateTrackable} interface with implementations
34+ * of the required methods in the interface and methods to manage
35+ * transitions in the state of the object.
36+ * Classes which wish to implement StateTrackable could create an
37+ * instance of this class and delegate all of their implementations
38+ * for {@code StateTrackable} methods to the corresponding methods
39+ * of this class.
40+ */
41+public final class StateTrackableDelegate implements StateTrackable {
42+ /**
43+ * The {@code UNTRACKABLE_DELEGATE} provides an implementation
44+ * of the StateTrackable interface that is permanently in the
45+ * {@link State#UNTRACKABLE UNTRACKABLE} state.
46+ */
47+ public final static StateTrackableDelegate UNTRACKABLE_DELEGATE =
48+ new StateTrackableDelegate(UNTRACKABLE);
49+
50+ /**
51+ * The {@code IMMUTABLE_DELEGATE} provides an implementation
52+ * of the StateTrackable interface that is permanently in the
53+ * {@link State#IMMUTABLE IMMUTABLE} state.
54+ */
55+ public final static StateTrackableDelegate IMMUTABLE_DELEGATE =
56+ new StateTrackableDelegate(IMMUTABLE);
57+
58+ /**
59+ * Returns a {@code StateTrackableDelegate} instance with the
60+ * specified initial {@link State State}.
61+ * If the specified {@code State} is
62+ * {@link State#UNTRACKABLE UNTRACKABLE} or
63+ * {@link State#IMMUTABLE IMMUTABLE}
64+ * then the approprirate static instance
65+ * {@link #UNTRACKABLE_DELEGATE} or {@link #IMMUTABLE_DELEGATE}
66+ * is returned.
67+ */
68+ public static StateTrackableDelegate createInstance(State state) {
69+ switch (state) {
70+ case UNTRACKABLE:
71+ return UNTRACKABLE_DELEGATE;
72+ case STABLE:
73+ return new StateTrackableDelegate(STABLE);
74+ case DYNAMIC:
75+ return new StateTrackableDelegate(DYNAMIC);
76+ case IMMUTABLE:
77+ return IMMUTABLE_DELEGATE;
78+ default:
79+ throw new InternalError("unknown state");
80+ }
81+ }
82+
83+ private State theState;
84+ StateTracker theTracker; // package private for easy access from tracker
85+ private int numDynamicAgents;
86+
87+ /**
88+ * Constructs a StateTrackableDelegate object with the specified
89+ * initial State.
90+ */
91+ private StateTrackableDelegate(State state) {
92+ this.theState = state;
93+ }
94+
95+ /**
96+ * @inheritDoc
97+ * @since 1.7
98+ */
99+ public State getState() {
100+ return theState;
101+ }
102+
103+ /**
104+ * @inheritDoc
105+ * @since 1.7
106+ */
107+ public synchronized StateTracker getStateTracker() {
108+ StateTracker st = theTracker;
109+ if (st == null) {
110+ switch (theState) {
111+ case IMMUTABLE:
112+ st = StateTracker.ALWAYS_CURRENT;
113+ break;
114+ case STABLE:
115+ st = new StateTracker() {
116+ public boolean isCurrent() {
117+ return (theTracker == this);
118+ }
119+ };
120+ break;
121+ case DYNAMIC:
122+ // We return the NEVER_CURRENT tracker, but that is
123+ // just temporary while we are in the DYNAMIC state.
124+ // NO BREAK
125+ case UNTRACKABLE:
126+ st = StateTracker.NEVER_CURRENT;
127+ break;
128+ }
129+ theTracker = st;
130+ }
131+ return st;
132+ }
133+
134+ /**
135+ * This method provides an easy way for delegating classes to
136+ * change the overall {@link State State} of the delegate to
137+ * {@link State#IMMUTABLE IMMUTABLE}.
138+ * @throws IllegalStateException if the current state is
139+ * {@link State#UNTRACKABLE UNTRACKABLE}
140+ * @see #setUntrackable
141+ * @since 1.7
142+ */
143+ public synchronized void setImmutable() {
144+ if (theState == UNTRACKABLE || theState == DYNAMIC) {
145+ throw new IllegalStateException("UNTRACKABLE or DYNAMIC "+
146+ "objects cannot become IMMUTABLE");
147+ }
148+ theState = IMMUTABLE;
149+ theTracker = null;
150+ }
151+
152+ /**
153+ * This method provides an easy way for delegating classes to
154+ * change the overall {@link State State} of the delegate to
155+ * {@link State#UNTRACKABLE UNTRACKABLE}.
156+ * This method is typically called when references to the
157+ * internal data buffers have been made public.
158+ * @throws IllegalStateException if the current state is
159+ * {@link State#IMMUTABLE IMMUTABLE}
160+ * @see #setImmutable
161+ * @since 1.7
162+ */
163+ public synchronized void setUntrackable() {
164+ if (theState == IMMUTABLE) {
165+ throw new IllegalStateException("IMMUTABLE objects cannot "+
166+ "become UNTRACKABLE");
167+ }
168+ theState = UNTRACKABLE;
169+ theTracker = null;
170+ }
171+
172+ /**
173+ * This method provides an easy way for delegating classes to
174+ * manage temporarily setting the overall {@link State State}
175+ * of the delegate to {@link State#DYNAMIC DYNAMIC}
176+ * during well-defined time frames of dynamic pixel updating.
177+ * This method should be called once before each flow of control
178+ * that might dynamically update the pixels in an uncontrolled
179+ * or unpredictable fashion.
180+ * <p>
181+ * The companion method {@link #removeDynamicAgent} method should
182+ * also be called once after each such flow of control has ended.
183+ * Failing to call the remove method will result in this object
184+ * permanently becoming {@link State#DYNAMIC DYNAMIC}
185+ * and therefore effectively untrackable.
186+ * <p>
187+ * This method will only change the {@link State State} of the
188+ * delegate if it is currently {@link State#STABLE STABLE}.
189+ *
190+ * @throws IllegalStateException if the current state is
191+ * {@link State#IMMUTABLE IMMUTABLE}
192+ * @since 1.7
193+ */
194+ public synchronized void addDynamicAgent() {
195+ if (theState == IMMUTABLE) {
196+ throw new IllegalStateException("Cannot change state from "+
197+ "IMMUTABLE");
198+ }
199+ ++numDynamicAgents;
200+ if (theState == STABLE) {
201+ theState = DYNAMIC;
202+ theTracker = null;
203+ }
204+ }
205+
206+ /**
207+ * This method provides an easy way for delegating classes to
208+ * manage restoring the overall {@link State State} of the
209+ * delegate back to {@link State#STABLE STABLE}
210+ * after a well-defined time frame of dynamic pixel updating.
211+ * This method should be called once after each flow of control
212+ * that might dynamically update the pixels in an uncontrolled
213+ * or unpredictable fashion has ended.
214+ * <p>
215+ * The companion method {@link #addDynamicAgent} method should
216+ * have been called at some point before each such flow of
217+ * control began.
218+ * If this method is called without having previously called
219+ * the add method, the {@link State State} of this object
220+ * will become unreliable.
221+ * <p>
222+ * This method will only change the {@link State State} of the
223+ * delegate if the number of outstanding dynamic agents has
224+ * gone to 0 and it is currently
225+ * {@link State#DYNAMIC DYNAMIC}.
226+ *
227+ * @since 1.7
228+ */
229+ protected synchronized void removeDynamicAgent() {
230+ if (--numDynamicAgents == 0 && theState == DYNAMIC) {
231+ theState = STABLE;
232+ theTracker = null;
233+ }
234+ }
235+
236+ /**
237+ * This method provides an easy way for delegating classes to
238+ * indicate that the contents have changed.
239+ * This method will invalidate outstanding StateTracker objects
240+ * so that any other agents which maintain cached information
241+ * about the pixels will know to refresh their cached copies.
242+ * This method should be called after every modification to
243+ * the data, such as any calls to any of the setElem methods.
244+ * <p>
245+ * Note that, for efficiency, this method does not check the
246+ * {@link State State} of the object to see if it is compatible
247+ * with being marked dirty
248+ * (i.e. not {@link State#IMMUTABLE IMMUTABLE}).
249+ * It is up to the callers to enforce the fact that an
250+ * {@code IMMUTABLE} delegate is never modified.
251+ * @since 1.7
252+ */
253+ public final void markDirty() {
254+ theTracker = null;
255+ }
256+}
java/pkg/sun/java2d/StateTracker$1.class+0−0

Binary file not shown.

java/pkg/sun/java2d/StateTracker$2.class+0−0

Binary file not shown.

java/pkg/sun/java2d/StateTracker.class+0−0

Binary file not shown.

java/pkg/sun/java2d/StateTracker.java+104−0
@@ -0,0 +1,104 @@
1+/*
2+ * Copyright (c) 2007, 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+
26+package sun.java2d;
27+
28+/**
29+ * This interface is used to track changes to the complex data of an
30+ * object that implements the StateTrackable interface.
31+ * <p>
32+ * The usage pattern for code accessing the trackable data is as follows:
33+ * <pre>
34+ * StateTrackable trackedobject;
35+ * MyInfo cacheddata;
36+ * StateTracker cachetracker;
37+ * public synchronized MyInfo getInfoAbout(StateTrackable obj) {
38+ * if (trackedobject != obj || !cachetracker.isCurrent()) {
39+ * // Note: Always call getStateTracker() before
40+ * // caching any data about the objct...
41+ * cachetracker = obj.getStateTracker();
42+ * cacheddata = calculateInfoFrom(obj);
43+ * trackedobject = obj;
44+ * }
45+ * return cacheddata;
46+ * }
47+ * </pre>
48+ * Note that the sample code above works correctly regardless of the
49+ * {@link StateTrackable.State State} of the complex data of the object,
50+ * but it may be inefficient to store precalculated information about
51+ * an object whose current {@link StateTrackable.State State} is
52+ * {@link StateTrackable.State#UNTRACKABLE UNTRACKABLE}
53+ * and it is unnecessary to perform the {@link #isCurrent} test for
54+ * data whose current {@link StateTrackable.State State} is
55+ * {@link StateTrackable.State#IMMUTABLE IMMUTABLE}.
56+ * Optimizations to the sample code for either or both of those terminal
57+ * States may be of benefit for some use cases, but is left out of the
58+ * example to reduce its complexity.
59+ *
60+ * @see StateTrackable.State
61+ * @since 1.7
62+ */
63+public interface StateTracker {
64+ /**
65+ * An implementation of the StateTracker interface which
66+ * always returns true.
67+ * This implementation is useful for objects whose current
68+ * {@link StateTrackable.State State} is
69+ * {@link StateTrackable.State#IMMUTABLE IMMUTABLE}.
70+ * @since 1.7
71+ */
72+ public StateTracker ALWAYS_CURRENT = new StateTracker() {
73+ public boolean isCurrent() {
74+ return true;
75+ }
76+ };
77+
78+ /**
79+ * An implementation of the StateTracker interface which
80+ * always returns false.
81+ * This implementation is useful for objects whose current
82+ * {@link StateTrackable.State State} is
83+ * {@link StateTrackable.State#UNTRACKABLE UNTRACKABLE}.
84+ * This implementation may also be useful for some objects
85+ * whose current {@link StateTrackable.State State} is
86+ * {@link StateTrackable.State#DYNAMIC DYNAMIC}.
87+ * @since 1.7
88+ */
89+ public StateTracker NEVER_CURRENT = new StateTracker() {
90+ public boolean isCurrent() {
91+ return false;
92+ }
93+ };
94+
95+ /**
96+ * Returns true iff the contents of the complex data of the
97+ * associated StateTrackable object have not changed since
98+ * the time that this StateTracker was returned from its
99+ * getStateTracker() method.
100+ * @see StateTrackable
101+ * @since 1.7
102+ */
103+ public boolean isCurrent();
104+}
java/pkg/sun/java2d/SunCompositeContext.class+0−0

Binary file not shown.

java/pkg/sun/java2d/SunCompositeContext.java+129−0
@@ -0,0 +1,129 @@
1+/*
2+ * Copyright (c) 1997, 2002, 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+
26+package sun.java2d;
27+
28+import java.awt.Composite;
29+import java.awt.CompositeContext;
30+import java.awt.AlphaComposite;
31+import java.awt.image.ColorModel;
32+import java.awt.image.BufferedImage;
33+import java.awt.image.Raster;
34+import java.awt.image.WritableRaster;
35+import sun.awt.image.BufImgSurfaceData;
36+import sun.java2d.loops.XORComposite;
37+import sun.java2d.loops.CompositeType;
38+import sun.java2d.loops.Blit;
39+
40+public class SunCompositeContext implements CompositeContext {
41+ ColorModel srcCM;
42+ ColorModel dstCM;
43+ Composite composite;
44+ CompositeType comptype;
45+
46+ public SunCompositeContext(AlphaComposite ac,
47+ ColorModel s, ColorModel d)
48+ {
49+ if (s == null) {
50+ throw new NullPointerException("Source color model cannot be null");
51+ }
52+ if (d == null) {
53+ throw new NullPointerException("Destination color model cannot be null");
54+ }
55+ srcCM = s;
56+ dstCM = d;
57+ this.composite = ac;
58+ this.comptype = CompositeType.forAlphaComposite(ac);
59+ }
60+
61+ public SunCompositeContext(XORComposite xc,
62+ ColorModel s, ColorModel d)
63+ {
64+ if (s == null) {
65+ throw new NullPointerException("Source color model cannot be null");
66+ }
67+ if (d == null) {
68+ throw new NullPointerException("Destination color model cannot be null");
69+ }
70+ srcCM = s;
71+ dstCM = d;
72+ this.composite = xc;
73+ this.comptype = CompositeType.Xor;
74+ }
75+
76+ /**
77+ * Release resources allocated for context.
78+ */
79+ public void dispose() {
80+ }
81+
82+ /**
83+ * This method composes the two source tiles
84+ * and places the result in the destination tile. Note that
85+ * the destination can be the same object as either
86+ * the first or second source.
87+ * @param src1 The first source tile for the compositing operation.
88+ * @param src2 The second source tile for the compositing operation.
89+ * @param dst The tile where the result of the operation is stored.
90+ */
91+ public void compose(Raster srcArg, Raster dstIn, WritableRaster dstOut) {
92+ WritableRaster src;
93+ int w;
94+ int h;
95+
96+ if (dstIn != dstOut) {
97+ dstOut.setDataElements(0, 0, dstIn);
98+ }
99+
100+ // REMIND: We should be able to create a SurfaceData from just
101+ // a non-writable Raster and a ColorModel. Since we need to
102+ // create a SurfaceData from a BufferedImage then we need to
103+ // make a WritableRaster since it is needed to construct a
104+ // BufferedImage.
105+ if (srcArg instanceof WritableRaster) {
106+ src = (WritableRaster) srcArg;
107+ } else {
108+ src = srcArg.createCompatibleWritableRaster();
109+ src.setDataElements(0, 0, srcArg);
110+ }
111+
112+ w = Math.min(src.getWidth(), dstIn.getWidth());
113+ h = Math.min(src.getHeight(), dstIn.getHeight());
114+
115+ BufferedImage srcImg = new BufferedImage(srcCM, src,
116+ srcCM.isAlphaPremultiplied(),
117+ null);
118+ BufferedImage dstImg = new BufferedImage(dstCM, dstOut,
119+ dstCM.isAlphaPremultiplied(),
120+ null);
121+
122+ SurfaceData srcData = BufImgSurfaceData.createData(srcImg);
123+ SurfaceData dstData = BufImgSurfaceData.createData(dstImg);
124+ Blit blit = Blit.getFromCache(srcData.getSurfaceType(),
125+ comptype,
126+ dstData.getSurfaceType());
127+ blit.Blit(srcData, dstData, composite, null, 0, 0, 0, 0, w, h);
128+ }
129+}
java/pkg/sun/java2d/SunGraphics2D.class+0−0

Binary file not shown.

java/pkg/sun/java2d/SunGraphics2D.java+3310−0
@@ -0,0 +1,3310 @@
1+/*
2+ * Copyright (c) 1996, 2008, 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+
26+package sun.java2d;
27+
28+import java.awt.Graphics;
29+import java.awt.Graphics2D;
30+import java.awt.RenderingHints;
31+import java.awt.RenderingHints.Key;
32+import java.awt.geom.Area;
33+import java.awt.geom.AffineTransform;
34+import java.awt.geom.NoninvertibleTransformException;
35+import java.awt.AlphaComposite;
36+import java.awt.BasicStroke;
37+import java.awt.image.BufferedImage;
38+import java.awt.image.BufferedImageOp;
39+import java.awt.image.RenderedImage;
40+import java.awt.image.renderable.RenderableImage;
41+import java.awt.image.renderable.RenderContext;
42+import java.awt.image.AffineTransformOp;
43+import java.awt.image.Raster;
44+import java.awt.image.WritableRaster;
45+import java.awt.Image;
46+import java.awt.Composite;
47+import java.awt.Color;
48+import java.awt.image.ColorModel;
49+import java.awt.GraphicsConfiguration;
50+import java.awt.Paint;
51+import java.awt.GradientPaint;
52+import java.awt.LinearGradientPaint;
53+import java.awt.RadialGradientPaint;
54+import java.awt.TexturePaint;
55+import java.awt.geom.Rectangle2D;
56+import java.awt.geom.PathIterator;
57+import java.awt.geom.GeneralPath;
58+import java.awt.Shape;
59+import java.awt.Stroke;
60+import java.awt.FontMetrics;
61+import java.awt.Rectangle;
62+import java.text.AttributedCharacterIterator;
63+import java.awt.Font;
64+import java.awt.image.ImageObserver;
65+import java.awt.Transparency;
66+import java.awt.font.GlyphVector;
67+import java.awt.font.TextLayout;
68+import sun.font.FontDesignMetrics;
69+import sun.font.FontUtilities;
70+import sun.java2d.pipe.PixelDrawPipe;
71+import sun.java2d.pipe.PixelFillPipe;
72+import sun.java2d.pipe.ShapeDrawPipe;
73+import sun.java2d.pipe.ValidatePipe;
74+import sun.java2d.pipe.ShapeSpanIterator;
75+import sun.java2d.pipe.Region;
76+import sun.java2d.pipe.TextPipe;
77+import sun.java2d.pipe.DrawImagePipe;
78+import sun.java2d.pipe.LoopPipe;
79+import sun.java2d.loops.FontInfo;
80+import sun.java2d.loops.RenderLoops;
81+import sun.java2d.loops.CompositeType;
82+import sun.java2d.loops.SurfaceType;
83+import sun.java2d.loops.Blit;
84+import sun.java2d.loops.MaskFill;
85+import sun.font.FontManager;
86+import java.awt.font.FontRenderContext;
87+import sun.java2d.loops.XORComposite;
88+import sun.awt.ConstrainableGraphics;
89+import sun.awt.SunHints;
90+import java.util.Map;
91+import java.util.Iterator;
92+import sun.java2d.DestSurfaceProvider;
93+import sun.misc.PerformanceLogger;
94+
95+/**
96+ * This is a the master Graphics2D superclass for all of the Sun
97+ * Graphics implementations. This class relies on subclasses to
98+ * manage the various device information, but provides an overall
99+ * general framework for performing all of the requests in the
100+ * Graphics and Graphics2D APIs.
101+ *
102+ * @author Jim Graham
103+ */
104+public final class SunGraphics2D
105+ extends Graphics2D
106+ implements ConstrainableGraphics, Cloneable, DestSurfaceProvider
107+{
108+ /*
109+ * Attribute States
110+ */
111+ /* Paint */
112+ public static final int PAINT_CUSTOM = 6; /* Any other Paint object */
113+ public static final int PAINT_TEXTURE = 5; /* Tiled Image */
114+ public static final int PAINT_RAD_GRADIENT = 4; /* Color RadialGradient */
115+ public static final int PAINT_LIN_GRADIENT = 3; /* Color LinearGradient */
116+ public static final int PAINT_GRADIENT = 2; /* Color Gradient */
117+ public static final int PAINT_ALPHACOLOR = 1; /* Non-opaque Color */
118+ public static final int PAINT_OPAQUECOLOR = 0; /* Opaque Color */
119+
120+ /* Composite*/
121+ public static final int COMP_CUSTOM = 3;/* Custom Composite */
122+ public static final int COMP_XOR = 2;/* XOR Mode Composite */
123+ public static final int COMP_ALPHA = 1;/* AlphaComposite */
124+ public static final int COMP_ISCOPY = 0;/* simple stores into destination,
125+ * i.e. Src, SrcOverNoEa, and other
126+ * alpha modes which replace
127+ * the destination.
128+ */
129+
130+ /* Stroke */
131+ public static final int STROKE_CUSTOM = 3; /* custom Stroke */
132+ public static final int STROKE_WIDE = 2; /* BasicStroke */
133+ public static final int STROKE_THINDASHED = 1; /* BasicStroke */
134+ public static final int STROKE_THIN = 0; /* BasicStroke */
135+
136+ /* Transform */
137+ public static final int TRANSFORM_GENERIC = 4; /* any 3x2 */
138+ public static final int TRANSFORM_TRANSLATESCALE = 3; /* scale XY */
139+ public static final int TRANSFORM_ANY_TRANSLATE = 2; /* non-int translate */
140+ public static final int TRANSFORM_INT_TRANSLATE = 1; /* int translate */
141+ public static final int TRANSFORM_ISIDENT = 0; /* Identity */
142+
143+ /* Clipping */
144+ public static final int CLIP_SHAPE = 2; /* arbitrary clip */
145+ public static final int CLIP_RECTANGULAR = 1; /* rectangular clip */
146+ public static final int CLIP_DEVICE = 0; /* no clipping set */
147+
148+ /* The following fields are used when the current Paint is a Color. */
149+ public int eargb; // ARGB value with ExtraAlpha baked in
150+ public int pixel; // pixel value for eargb
151+
152+ public SurfaceData surfaceData;
153+
154+ public PixelDrawPipe drawpipe;
155+ public PixelFillPipe fillpipe;
156+ public DrawImagePipe imagepipe;
157+ public ShapeDrawPipe shapepipe;
158+ public TextPipe textpipe;
159+ public MaskFill alphafill;
160+
161+ public RenderLoops loops;
162+
163+ public CompositeType imageComp; /* Image Transparency checked on fly */
164+
165+ public int paintState;
166+ public int compositeState;
167+ public int strokeState;
168+ public int transformState;
169+ public int clipState;
170+
171+ public Color foregroundColor;
172+ public Color backgroundColor;
173+
174+ public AffineTransform transform;
175+ public int transX;
176+ public int transY;
177+
178+ protected static final Stroke defaultStroke = new BasicStroke();
179+ protected static final Composite defaultComposite = AlphaComposite.SrcOver;
180+ private static final Font defaultFont =
181+ new Font(Font.DIALOG, Font.PLAIN, 12);
182+
183+ public Paint paint;
184+ public Stroke stroke;
185+ public Composite composite;
186+ protected Font font;
187+ protected FontMetrics fontMetrics;
188+
189+ public int renderHint;
190+ public int antialiasHint;
191+ public int textAntialiasHint;
192+ private int fractionalMetricsHint;
193+
194+ /* A gamma adjustment to the colour used in lcd text blitting */
195+ public int lcdTextContrast;
196+ private static int lcdTextContrastDefaultValue = 140;
197+
198+ private int interpolationHint; // raw value of rendering Hint
199+ public int strokeHint;
200+
201+ public int interpolationType; // algorithm choice based on
202+ // interpolation and render Hints
203+
204+ public RenderingHints hints;
205+
206+ public Region constrainClip; // lightweight bounds
207+ public int constrainX;
208+ public int constrainY;
209+
210+ public Region clipRegion;
211+ public Shape usrClip;
212+ protected Region devClip; // Actual physical drawable
213+
214+ // cached state for text rendering
215+ private boolean validFontInfo;
216+ private FontInfo fontInfo;
217+ private FontInfo glyphVectorFontInfo;
218+ private FontRenderContext glyphVectorFRC;
219+
220+ private final static int slowTextTransformMask =
221+ AffineTransform.TYPE_GENERAL_TRANSFORM
222+ | AffineTransform.TYPE_MASK_ROTATION
223+ | AffineTransform.TYPE_FLIP;
224+
225+ static {
226+ if (PerformanceLogger.loggingEnabled()) {
227+ PerformanceLogger.setTime("SunGraphics2D static initialization");
228+ }
229+ }
230+
231+ public SunGraphics2D(SurfaceData sd, Color fg, Color bg, Font f) {
232+ surfaceData = sd;
233+ foregroundColor = fg;
234+ backgroundColor = bg;
235+
236+ transform = new AffineTransform();
237+ stroke = defaultStroke;
238+ composite = defaultComposite;
239+ paint = foregroundColor;
240+
241+ imageComp = CompositeType.SrcOverNoEa;
242+
243+ renderHint = SunHints.INTVAL_RENDER_DEFAULT;
244+ antialiasHint = SunHints.INTVAL_ANTIALIAS_OFF;
245+ textAntialiasHint = SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT;
246+ fractionalMetricsHint = SunHints.INTVAL_FRACTIONALMETRICS_OFF;
247+ lcdTextContrast = lcdTextContrastDefaultValue;
248+ interpolationHint = -1;
249+ strokeHint = SunHints.INTVAL_STROKE_DEFAULT;
250+
251+ interpolationType = AffineTransformOp.TYPE_NEAREST_NEIGHBOR;
252+
253+ validateColor();
254+
255+ font = f;
256+ if (font == null) {
257+ font = defaultFont;
258+ }
259+
260+ setDevClip(sd.getBounds());
261+ invalidatePipe();
262+ }
263+
264+ protected Object clone() {
265+ try {
266+ SunGraphics2D g = (SunGraphics2D) super.clone();
267+ g.transform = new AffineTransform(this.transform);
268+ if (hints != null) {
269+ g.hints = (RenderingHints) this.hints.clone();
270+ }
271+ /* FontInfos are re-used, so must be cloned too, if they
272+ * are valid, and be nulled out if invalid.
273+ * The implied trade-off is that there is more to be gained
274+ * from re-using these objects than is lost by having to
275+ * clone them when the SG2D is cloned.
276+ */
277+ if (this.fontInfo != null) {
278+ if (this.validFontInfo) {
279+ g.fontInfo = (FontInfo)this.fontInfo.clone();
280+ } else {
281+ g.fontInfo = null;
282+ }
283+ }
284+ if (this.glyphVectorFontInfo != null) {
285+ g.glyphVectorFontInfo =
286+ (FontInfo)this.glyphVectorFontInfo.clone();
287+ g.glyphVectorFRC = this.glyphVectorFRC;
288+ }
289+ //g.invalidatePipe();
290+ return g;
291+ } catch (CloneNotSupportedException e) {
292+ }
293+ return null;
294+ }
295+
296+ /**
297+ * Create a new SunGraphics2D based on this one.
298+ */
299+ public Graphics create() {
300+ return (Graphics) clone();
301+ }
302+
303+ public void setDevClip(int x, int y, int w, int h) {
304+ Region c = constrainClip;
305+ if (c == null) {
306+ devClip = Region.getInstanceXYWH(x, y, w, h);
307+ } else {
308+ devClip = c.getIntersectionXYWH(x, y, w, h);
309+ }
310+ validateCompClip();
311+ }
312+
313+ public void setDevClip(Rectangle r) {
314+ setDevClip(r.x, r.y, r.width, r.height);
315+ }
316+
317+ /**
318+ * Constrain rendering for lightweight objects.
319+ *
320+ * REMIND: This method will back off to the "workaround"
321+ * of using translate and clipRect if the Graphics
322+ * to be constrained has a complex transform. The
323+ * drawback of the workaround is that the resulting
324+ * clip and device origin cannot be "enforced".
325+ *
326+ * @exception IllegalStateException If the Graphics
327+ * to be constrained has a complex transform.
328+ */
329+ public void constrain(int x, int y, int w, int h) {
330+ if ((x|y) != 0) {
331+ translate(x, y);
332+ }
333+ if (transformState >= TRANSFORM_TRANSLATESCALE) {
334+ clipRect(0, 0, w, h);
335+ return;
336+ }
337+ x = constrainX = transX;
338+ y = constrainY = transY;
339+ w = Region.dimAdd(x, w);
340+ h = Region.dimAdd(y, h);
341+ Region c = constrainClip;
342+ if (c == null) {
343+ c = Region.getInstanceXYXY(x, y, w, h);
344+ } else {
345+ c = c.getIntersectionXYXY(x, y, w, h);
346+ if (c == constrainClip) {
347+ // Common case to ignore
348+ return;
349+ }
350+ }
351+ constrainClip = c;
352+ if (!devClip.isInsideQuickCheck(c)) {
353+ devClip = devClip.getIntersection(c);
354+ validateCompClip();
355+ }
356+ }
357+
358+ protected static ValidatePipe invalidpipe = new ValidatePipe();
359+
360+ /*
361+ * Invalidate the pipeline
362+ */
363+ protected void invalidatePipe() {
364+ drawpipe = invalidpipe;
365+ fillpipe = invalidpipe;
366+ shapepipe = invalidpipe;
367+ textpipe = invalidpipe;
368+ imagepipe = invalidpipe;
369+ loops = null;
370+ }
371+
372+ public void validatePipe() {
373+ surfaceData.validatePipe(this);
374+ }
375+
376+ /*
377+ * Intersect two Shapes by the simplest method, attempting to produce
378+ * a simplified result.
379+ * The boolean arguments keep1 and keep2 specify whether or not
380+ * the first or second shapes can be modified during the operation
381+ * or whether that shape must be "kept" unmodified.
382+ */
383+ Shape intersectShapes(Shape s1, Shape s2, boolean keep1, boolean keep2) {
384+ if (s1 instanceof Rectangle && s2 instanceof Rectangle) {
385+ return ((Rectangle) s1).intersection((Rectangle) s2);
386+ }
387+ if (s1 instanceof Rectangle2D) {
388+ return intersectRectShape((Rectangle2D) s1, s2, keep1, keep2);
389+ } else if (s2 instanceof Rectangle2D) {
390+ return intersectRectShape((Rectangle2D) s2, s1, keep2, keep1);
391+ }
392+ return intersectByArea(s1, s2, keep1, keep2);
393+ }
394+
395+ /*
396+ * Intersect a Rectangle with a Shape by the simplest method,
397+ * attempting to produce a simplified result.
398+ * The boolean arguments keep1 and keep2 specify whether or not
399+ * the first or second shapes can be modified during the operation
400+ * or whether that shape must be "kept" unmodified.
401+ */
402+ Shape intersectRectShape(Rectangle2D r, Shape s,
403+ boolean keep1, boolean keep2) {
404+ if (s instanceof Rectangle2D) {
405+ Rectangle2D r2 = (Rectangle2D) s;
406+ Rectangle2D outrect;
407+ if (!keep1) {
408+ outrect = r;
409+ } else if (!keep2) {
410+ outrect = r2;
411+ } else {
412+ outrect = new Rectangle2D.Float();
413+ }
414+ double x1 = Math.max(r.getX(), r2.getX());
415+ double x2 = Math.min(r.getX() + r.getWidth(),
416+ r2.getX() + r2.getWidth());
417+ double y1 = Math.max(r.getY(), r2.getY());
418+ double y2 = Math.min(r.getY() + r.getHeight(),
419+ r2.getY() + r2.getHeight());
420+
421+ if (((x2 - x1) < 0) || ((y2 - y1) < 0))
422+ // Width or height is negative. No intersection.
423+ outrect.setFrameFromDiagonal(0, 0, 0, 0);
424+ else
425+ outrect.setFrameFromDiagonal(x1, y1, x2, y2);
426+ return outrect;
427+ }
428+ if (r.contains(s.getBounds2D())) {
429+ if (keep2) {
430+ s = cloneShape(s);
431+ }
432+ return s;
433+ }
434+ return intersectByArea(r, s, keep1, keep2);
435+ }
436+
437+ protected static Shape cloneShape(Shape s) {
438+ return new GeneralPath(s);
439+ }
440+
441+ /*
442+ * Intersect two Shapes using the Area class. Presumably other
443+ * attempts at simpler intersection methods proved fruitless.
444+ * The boolean arguments keep1 and keep2 specify whether or not
445+ * the first or second shapes can be modified during the operation
446+ * or whether that shape must be "kept" unmodified.
447+ * @see #intersectShapes
448+ * @see #intersectRectShape
449+ */
450+ Shape intersectByArea(Shape s1, Shape s2, boolean keep1, boolean keep2) {
451+ Area a1, a2;
452+
453+ // First see if we can find an overwriteable source shape
454+ // to use as our destination area to avoid duplication.
455+ if (!keep1 && (s1 instanceof Area)) {
456+ a1 = (Area) s1;
457+ } else if (!keep2 && (s2 instanceof Area)) {
458+ a1 = (Area) s2;
459+ s2 = s1;
460+ } else {
461+ a1 = new Area(s1);
462+ }
463+
464+ if (s2 instanceof Area) {
465+ a2 = (Area) s2;
466+ } else {
467+ a2 = new Area(s2);
468+ }
469+
470+ a1.intersect(a2);
471+ if (a1.isRectangular()) {
472+ return a1.getBounds();
473+ }
474+
475+ return a1;
476+ }
477+
478+ /*
479+ * Intersect usrClip bounds and device bounds to determine the composite
480+ * rendering boundaries.
481+ */
482+ public Region getCompClip() {
483+ if (!surfaceData.isValid()) {
484+ // revalidateAll() implicitly recalculcates the composite clip
485+ revalidateAll();
486+ }
487+
488+ return clipRegion;
489+ }
490+
491+ public Font getFont() {
492+ if (font == null) {
493+ font = defaultFont;
494+ }
495+ return font;
496+ }
497+
498+ private static final double[] IDENT_MATRIX = {1, 0, 0, 1};
499+ private static final AffineTransform IDENT_ATX =
500+ new AffineTransform();
501+
502+ private static final int MINALLOCATED = 8;
503+ private static final int TEXTARRSIZE = 17;
504+ private static double[][] textTxArr = new double[TEXTARRSIZE][];
505+ private static AffineTransform[] textAtArr =
506+ new AffineTransform[TEXTARRSIZE];
507+
508+ static {
509+ for (int i=MINALLOCATED;i<TEXTARRSIZE;i++) {
510+ textTxArr[i] = new double [] {i, 0, 0, i};
511+ textAtArr[i] = new AffineTransform( textTxArr[i]);
512+ }
513+ }
514+
515+ // cached state for various draw[String,Char,Byte] optimizations
516+ public FontInfo checkFontInfo(FontInfo info, Font font,
517+ FontRenderContext frc) {
518+ /* Do not create a FontInfo object as part of construction of an
519+ * SG2D as its possible it may never be needed - ie if no text
520+ * is drawn using this SG2D.
521+ */
522+ if (info == null) {
523+ info = new FontInfo();
524+ }
525+
526+ float ptSize = font.getSize2D();
527+ int txFontType;
528+ AffineTransform devAt, textAt=null;
529+ if (font.isTransformed()) {
530+ textAt = font.getTransform();
531+ textAt.scale(ptSize, ptSize);
532+ txFontType = textAt.getType();
533+ info.originX = (float)textAt.getTranslateX();
534+ info.originY = (float)textAt.getTranslateY();
535+ textAt.translate(-info.originX, -info.originY);
536+ if (transformState >= TRANSFORM_TRANSLATESCALE) {
537+ transform.getMatrix(info.devTx = new double[4]);
538+ devAt = new AffineTransform(info.devTx);
539+ textAt.preConcatenate(devAt);
540+ } else {
541+ info.devTx = IDENT_MATRIX;
542+ devAt = IDENT_ATX;
543+ }
544+ textAt.getMatrix(info.glyphTx = new double[4]);
545+ double shearx = textAt.getShearX();
546+ double scaley = textAt.getScaleY();
547+ if (shearx != 0) {
548+ scaley = Math.sqrt(shearx * shearx + scaley * scaley);
549+ }
550+ info.pixelHeight = (int)(Math.abs(scaley)+0.5);
551+ } else {
552+ txFontType = AffineTransform.TYPE_IDENTITY;
553+ info.originX = info.originY = 0;
554+ if (transformState >= TRANSFORM_TRANSLATESCALE) {
555+ transform.getMatrix(info.devTx = new double[4]);
556+ devAt = new AffineTransform(info.devTx);
557+ info.glyphTx = new double[4];
558+ for (int i = 0; i < 4; i++) {
559+ info.glyphTx[i] = info.devTx[i] * ptSize;
560+ }
561+ textAt = new AffineTransform(info.glyphTx);
562+ double shearx = transform.getShearX();
563+ double scaley = transform.getScaleY();
564+ if (shearx != 0) {
565+ scaley = Math.sqrt(shearx * shearx + scaley * scaley);
566+ }
567+ info.pixelHeight = (int)(Math.abs(scaley * ptSize)+0.5);
568+ } else {
569+ /* If the double represents a common integral, we
570+ * may have pre-allocated objects.
571+ * A "sparse" array be seems to be as fast as a switch
572+ * even for 3 or 4 pt sizes, and is more flexible.
573+ * This should perform comparably in single-threaded
574+ * rendering to the old code which synchronized on the
575+ * class and scale better on MP systems.
576+ */
577+ int pszInt = (int)ptSize;
578+ if (ptSize == pszInt &&
579+ pszInt >= MINALLOCATED && pszInt < TEXTARRSIZE) {
580+ info.glyphTx = textTxArr[pszInt];
581+ textAt = textAtArr[pszInt];
582+ info.pixelHeight = pszInt;
583+ } else {
584+ info.pixelHeight = (int)(ptSize+0.5);
585+ }
586+ if (textAt == null) {
587+ info.glyphTx = new double[] {ptSize, 0, 0, ptSize};
588+ textAt = new AffineTransform(info.glyphTx);
589+ }
590+
591+ info.devTx = IDENT_MATRIX;
592+ devAt = IDENT_ATX;
593+ }
594+ }
595+
596+ info.font2D = FontUtilities.getFont2D(font);
597+
598+ int fmhint = fractionalMetricsHint;
599+ if (fmhint == SunHints.INTVAL_FRACTIONALMETRICS_DEFAULT) {
600+ fmhint = SunHints.INTVAL_FRACTIONALMETRICS_OFF;
601+ }
602+ info.lcdSubPixPos = false; // conditionally set true in LCD mode.
603+
604+ /* The text anti-aliasing hints that are set by the client need
605+ * to be interpreted for the current state and stored in the
606+ * FontInfo.aahint which is what will actually be used and
607+ * will be one of OFF, ON, LCD_HRGB or LCD_VRGB.
608+ * This is what pipe selection code should typically refer to, not
609+ * textAntialiasHint. This means we are now evaluating the meaning
610+ * of "default" here. Any pipe that really cares about that will
611+ * also need to consult that variable.
612+ * Otherwise these are being used only as args to getStrike,
613+ * and are encapsulated in that object which is part of the
614+ * FontInfo, so we do not need to store them directly as fields
615+ * in the FontInfo object.
616+ * That could change if FontInfo's were more selectively
617+ * revalidated when graphics state changed. Presently this
618+ * method re-evaluates all fields in the fontInfo.
619+ * The strike doesn't need to know the RGB subpixel order. Just
620+ * if its H or V orientation, so if an LCD option is specified we
621+ * always pass in the RGB hint to the strike.
622+ * frc is non-null only if this is a GlyphVector. For reasons
623+ * which are probably a historical mistake the AA hint in a GV
624+ * is honoured when we render, overriding the Graphics setting.
625+ */
626+ int aahint;
627+ if (frc == null) {
628+ aahint = textAntialiasHint;
629+ } else {
630+ aahint = ((SunHints.Value)frc.getAntiAliasingHint()).getIndex();
631+ }
632+ if (aahint == SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT) {
633+ if (antialiasHint == SunHints.INTVAL_ANTIALIAS_ON) {
634+ aahint = SunHints.INTVAL_TEXT_ANTIALIAS_ON;
635+ } else {
636+ aahint = SunHints.INTVAL_TEXT_ANTIALIAS_OFF;
637+ }
638+ } else {
639+ /* If we are in checkFontInfo because a rendering hint has been
640+ * set then all pipes are revalidated. But we can also
641+ * be here because setFont() has been called when the 'gasp'
642+ * hint is set, as then the font size determines the text pipe.
643+ * See comments in SunGraphics2d.setFont(Font).
644+ */
645+ if (aahint == SunHints.INTVAL_TEXT_ANTIALIAS_GASP) {
646+ if (info.font2D.useAAForPtSize(info.pixelHeight)) {
647+ aahint = SunHints.INTVAL_TEXT_ANTIALIAS_ON;
648+ } else {
649+ aahint = SunHints.INTVAL_TEXT_ANTIALIAS_OFF;
650+ }
651+ } else if (aahint >= SunHints.INTVAL_TEXT_ANTIALIAS_LCD_HRGB) {
652+ /* loops for default rendering modes are installed in the SG2D
653+ * constructor. If there are none this will be null.
654+ * Not all compositing modes update the render loops, so
655+ * we also test that this is a mode we know should support
656+ * this. One minor issue is that the loops aren't necessarily
657+ * installed for a new rendering mode until after this
658+ * method is called during pipeline validation. So it is
659+ * theoretically possible that it was set to null for a
660+ * compositing mode, the composite is then set back to Src,
661+ * but the loop is still null when this is called and AA=ON
662+ * is installed instead of an LCD mode.
663+ * However this is done in the right order in SurfaceData.java
664+ * so this is not likely to be a problem - but not
665+ * guaranteed.
666+ */
667+ if (
668+ !surfaceData.canRenderLCDText(this)
669+// loops.drawGlyphListLCDLoop == null ||
670+// compositeState > COMP_ISCOPY ||
671+// paintState > PAINT_ALPHACOLOR
672+ ) {
673+ aahint = SunHints.INTVAL_TEXT_ANTIALIAS_ON;
674+ } else {
675+ info.lcdRGBOrder = true;
676+ /* Collapse these into just HRGB or VRGB.
677+ * Pipe selection code needs only to test for these two.
678+ * Since these both select the same pipe anyway its
679+ * tempting to collapse into one value. But they are
680+ * different strikes (glyph caches) so the distinction
681+ * needs to be made for that purpose.
682+ */
683+ if (aahint == SunHints.INTVAL_TEXT_ANTIALIAS_LCD_HBGR) {
684+ aahint = SunHints.INTVAL_TEXT_ANTIALIAS_LCD_HRGB;
685+ info.lcdRGBOrder = false;
686+ } else if
687+ (aahint == SunHints.INTVAL_TEXT_ANTIALIAS_LCD_VBGR) {
688+ aahint = SunHints.INTVAL_TEXT_ANTIALIAS_LCD_VRGB;
689+ info.lcdRGBOrder = false;
690+ }
691+ /* Support subpixel positioning only for the case in
692+ * which the horizontal resolution is increased
693+ */
694+ info.lcdSubPixPos =
695+ fmhint == SunHints.INTVAL_FRACTIONALMETRICS_ON &&
696+ aahint == SunHints.INTVAL_TEXT_ANTIALIAS_LCD_HRGB;
697+ }
698+ }
699+ }
700+ info.aaHint = aahint;
701+ info.fontStrike = info.font2D.getStrike(font, devAt, textAt,
702+ aahint, fmhint);
703+ return info;
704+ }
705+
706+ public static boolean isRotated(double [] mtx) {
707+ if ((mtx[0] == mtx[3]) &&
708+ (mtx[1] == 0.0) &&
709+ (mtx[2] == 0.0) &&
710+ (mtx[0] > 0.0))
711+ {
712+ return false;
713+ }
714+
715+ return true;
716+ }
717+
718+ public void setFont(Font font) {
719+ /* replacing the reference equality test font != this.font with
720+ * !font.equals(this.font) did not yield any measurable difference
721+ * in testing, but there may be yet to be identified cases where it
722+ * is beneficial.
723+ */
724+ if (font != null && font!=this.font/*!font.equals(this.font)*/) {
725+ /* In the GASP AA case the textpipe depends on the glyph size
726+ * as determined by graphics and font transforms as well as the
727+ * font size, and information in the font. But we may invalidate
728+ * the pipe only to find that it made no difference.
729+ * Deferring pipe invalidation to checkFontInfo won't work because
730+ * when called we may already be rendering to the wrong pipe.
731+ * So, if the font is transformed, or the graphics has more than
732+ * a simple scale, we'll take that as enough of a hint to
733+ * revalidate everything. But if they aren't we will
734+ * use the font's point size to query the gasp table and see if
735+ * what it says matches what's currently being used, in which
736+ * case there's no need to invalidate the textpipe.
737+ * This should be sufficient for all typical uses cases.
738+ */
739+ if (textAntialiasHint == SunHints.INTVAL_TEXT_ANTIALIAS_GASP &&
740+ textpipe != invalidpipe &&
741+ (transformState > TRANSFORM_ANY_TRANSLATE ||
742+ font.isTransformed() ||
743+ fontInfo == null || // Precaution, if true shouldn't get here
744+ (fontInfo.aaHint == SunHints.INTVAL_TEXT_ANTIALIAS_ON) !=
745+ FontUtilities.getFont2D(font).
746+ useAAForPtSize(font.getSize()))) {
747+ textpipe = invalidpipe;
748+ }
749+ this.font = font;
750+ this.fontMetrics = null;
751+ this.validFontInfo = false;
752+ }
753+ }
754+
755+ public FontInfo getFontInfo() {
756+ if (!validFontInfo) {
757+ this.fontInfo = checkFontInfo(this.fontInfo, font, null);
758+ validFontInfo = true;
759+ }
760+ return this.fontInfo;
761+ }
762+
763+ /* Used by drawGlyphVector which specifies its own font. */
764+ public FontInfo getGVFontInfo(Font font, FontRenderContext frc) {
765+ if (glyphVectorFontInfo != null &&
766+ glyphVectorFontInfo.font == font &&
767+ glyphVectorFRC == frc) {
768+ return glyphVectorFontInfo;
769+ } else {
770+ glyphVectorFRC = frc;
771+ return glyphVectorFontInfo =
772+ checkFontInfo(glyphVectorFontInfo, font, frc);
773+ }
774+ }
775+
776+ public FontMetrics getFontMetrics() {
777+ if (this.fontMetrics != null) {
778+ return this.fontMetrics;
779+ }
780+ /* NB the constructor and the setter disallow "font" being null */
781+ return this.fontMetrics =
782+ FontDesignMetrics.getMetrics(font, getFontRenderContext());
783+ }
784+
785+ public FontMetrics getFontMetrics(Font font) {
786+ if ((this.fontMetrics != null) && (font == this.font)) {
787+ return this.fontMetrics;
788+ }
789+ FontMetrics fm =
790+ FontDesignMetrics.getMetrics(font, getFontRenderContext());
791+
792+ if (this.font == font) {
793+ this.fontMetrics = fm;
794+ }
795+ return fm;
796+ }
797+
798+ /**
799+ * Checks to see if a Path intersects the specified Rectangle in device
800+ * space. The rendering attributes taken into account include the
801+ * clip, transform, and stroke attributes.
802+ * @param rect The area in device space to check for a hit.
803+ * @param p The path to check for a hit.
804+ * @param onStroke Flag to choose between testing the stroked or
805+ * the filled path.
806+ * @return True if there is a hit, false otherwise.
807+ * @see #setStroke
808+ * @see #fillPath
809+ * @see #drawPath
810+ * @see #transform
811+ * @see #setTransform
812+ * @see #clip
813+ * @see #setClip
814+ */
815+ public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
816+ if (onStroke) {
817+ s = stroke.createStrokedShape(s);
818+ }
819+
820+ s = transformShape(s);
821+ if ((constrainX|constrainY) != 0) {
822+ rect = new Rectangle(rect);
823+ rect.translate(constrainX, constrainY);
824+ }
825+
826+ return s.intersects(rect);
827+ }
828+
829+ /**
830+ * Return the ColorModel associated with this Graphics2D.
831+ */
832+ public ColorModel getDeviceColorModel() {
833+ return surfaceData.getColorModel();
834+ }
835+
836+ /**
837+ * Return the device configuration associated with this Graphics2D.
838+ */
839+ public GraphicsConfiguration getDeviceConfiguration() {
840+ return surfaceData.getDeviceConfiguration();
841+ }
842+
843+ /**
844+ * Return the SurfaceData object assigned to manage the destination
845+ * drawable surface of this Graphics2D.
846+ */
847+ public final SurfaceData getSurfaceData() {
848+ return surfaceData;
849+ }
850+
851+ /**
852+ * Sets the Composite in the current graphics state. Composite is used
853+ * in all drawing methods such as drawImage, drawString, drawPath,
854+ * and fillPath. It specifies how new pixels are to be combined with
855+ * the existing pixels on the graphics device in the rendering process.
856+ * @param comp The Composite object to be used for drawing.
857+ * @see java.awt.Graphics#setXORMode
858+ * @see java.awt.Graphics#setPaintMode
859+ * @see AlphaComposite
860+ */
861+ public void setComposite(Composite comp) {
862+ if (composite == comp) {
863+ return;
864+ }
865+ int newCompState;
866+ CompositeType newCompType;
867+ if (comp instanceof AlphaComposite) {
868+ AlphaComposite alphacomp = (AlphaComposite) comp;
869+ newCompType = CompositeType.forAlphaComposite(alphacomp);
870+ if (newCompType == CompositeType.SrcOverNoEa) {
871+ if (paintState == PAINT_OPAQUECOLOR ||
872+ (paintState > PAINT_ALPHACOLOR &&
873+ paint.getTransparency() == Transparency.OPAQUE))
874+ {
875+ newCompState = COMP_ISCOPY;
876+ } else {
877+ newCompState = COMP_ALPHA;
878+ }
879+ } else if (newCompType == CompositeType.SrcNoEa ||
880+ newCompType == CompositeType.Src ||
881+ newCompType == CompositeType.Clear)
882+ {
883+ newCompState = COMP_ISCOPY;
884+ } else if (surfaceData.getTransparency() == Transparency.OPAQUE &&
885+ newCompType == CompositeType.SrcIn)
886+ {
887+ newCompState = COMP_ISCOPY;
888+ } else {
889+ newCompState = COMP_ALPHA;
890+ }
891+ } else if (comp instanceof XORComposite) {
892+ newCompState = COMP_XOR;
893+ newCompType = CompositeType.Xor;
894+ } else if (comp == null) {
895+ throw new IllegalArgumentException("null Composite");
896+ } else {
897+ surfaceData.checkCustomComposite();
898+ newCompState = COMP_CUSTOM;
899+ newCompType = CompositeType.General;
900+ }
901+ if (compositeState != newCompState ||
902+ imageComp != newCompType)
903+ {
904+ compositeState = newCompState;
905+ imageComp = newCompType;
906+ invalidatePipe();
907+ validFontInfo = false;
908+ }
909+ composite = comp;
910+ if (paintState <= PAINT_ALPHACOLOR) {
911+ validateColor();
912+ }
913+ }
914+
915+ /**
916+ * Sets the Paint in the current graphics state.
917+ * @param paint The Paint object to be used to generate color in
918+ * the rendering process.
919+ * @see java.awt.Graphics#setColor
920+ * @see GradientPaint
921+ * @see TexturePaint
922+ */
923+ public void setPaint(Paint paint) {
924+ if (paint instanceof Color) {
925+ setColor((Color) paint);
926+ return;
927+ }
928+ if (paint == null || this.paint == paint) {
929+ return;
930+ }
931+ this.paint = paint;
932+ if (imageComp == CompositeType.SrcOverNoEa) {
933+ // special case where compState depends on opacity of paint
934+ if (paint.getTransparency() == Transparency.OPAQUE) {
935+ if (compositeState != COMP_ISCOPY) {
936+ compositeState = COMP_ISCOPY;
937+ }
938+ } else {
939+ if (compositeState == COMP_ISCOPY) {
940+ compositeState = COMP_ALPHA;
941+ }
942+ }
943+ }
944+ Class paintClass = paint.getClass();
945+ if (paintClass == GradientPaint.class) {
946+ paintState = PAINT_GRADIENT;
947+ } else if (paintClass == LinearGradientPaint.class) {
948+ paintState = PAINT_LIN_GRADIENT;
949+ } else if (paintClass == RadialGradientPaint.class) {
950+ paintState = PAINT_RAD_GRADIENT;
951+ } else if (paintClass == TexturePaint.class) {
952+ paintState = PAINT_TEXTURE;
953+ } else {
954+ paintState = PAINT_CUSTOM;
955+ }
956+ validFontInfo = false;
957+ invalidatePipe();
958+ }
959+
960+ static final int NON_UNIFORM_SCALE_MASK =
961+ (AffineTransform.TYPE_GENERAL_TRANSFORM |
962+ AffineTransform.TYPE_GENERAL_SCALE);
963+ public static final double MinPenSizeAA =
964+ sun.java2d.pipe.RenderingEngine.getInstance().getMinimumAAPenSize();
965+ public static final double MinPenSizeAASquared =
966+ (MinPenSizeAA * MinPenSizeAA);
967+ // Since inaccuracies in the trig package can cause us to
968+ // calculated a rotated pen width of just slightly greater
969+ // than 1.0, we add a fudge factor to our comparison value
970+ // here so that we do not misclassify single width lines as
971+ // wide lines under certain rotations.
972+ public static final double MinPenSizeSquared = 1.000000001;
973+
974+ private void validateBasicStroke(BasicStroke bs) {
975+ boolean aa = (antialiasHint == SunHints.INTVAL_ANTIALIAS_ON);
976+ if (transformState < TRANSFORM_TRANSLATESCALE) {
977+ if (aa) {
978+ if (bs.getLineWidth() <= MinPenSizeAA) {
979+ if (bs.getDashArray() == null) {
980+ strokeState = STROKE_THIN;
981+ } else {
982+ strokeState = STROKE_THINDASHED;
983+ }
984+ } else {
985+ strokeState = STROKE_WIDE;
986+ }
987+ } else {
988+ if (bs == defaultStroke) {
989+ strokeState = STROKE_THIN;
990+ } else if (bs.getLineWidth() <= 1.0f) {
991+ if (bs.getDashArray() == null) {
992+ strokeState = STROKE_THIN;
993+ } else {
994+ strokeState = STROKE_THINDASHED;
995+ }
996+ } else {
997+ strokeState = STROKE_WIDE;
998+ }
999+ }
1000+ } else {
1001+ double widthsquared;
1002+ if ((transform.getType() & NON_UNIFORM_SCALE_MASK) == 0) {
1003+ /* sqrt omitted, compare to squared limits below. */
1004+ widthsquared = Math.abs(transform.getDeterminant());
1005+ } else {
1006+ /* First calculate the "maximum scale" of this transform. */
1007+ double A = transform.getScaleX(); // m00
1008+ double C = transform.getShearX(); // m01
1009+ double B = transform.getShearY(); // m10
1010+ double D = transform.getScaleY(); // m11
1011+
1012+ /*
1013+ * Given a 2 x 2 affine matrix [ A B ] such that
1014+ * [ C D ]
1015+ * v' = [x' y'] = [Ax + Cy, Bx + Dy], we want to
1016+ * find the maximum magnitude (norm) of the vector v'
1017+ * with the constraint (x^2 + y^2 = 1).
1018+ * The equation to maximize is
1019+ * |v'| = sqrt((Ax+Cy)^2+(Bx+Dy)^2)
1020+ * or |v'| = sqrt((AA+BB)x^2 + 2(AC+BD)xy + (CC+DD)y^2).
1021+ * Since sqrt is monotonic we can maximize |v'|^2
1022+ * instead and plug in the substitution y = sqrt(1 - x^2).
1023+ * Trigonometric equalities can then be used to get
1024+ * rid of most of the sqrt terms.
1025+ */
1026+ double EA = A*A + B*B; // x^2 coefficient
1027+ double EB = 2*(A*C + B*D); // xy coefficient
1028+ double EC = C*C + D*D; // y^2 coefficient
1029+
1030+ /*
1031+ * There is a lot of calculus omitted here.
1032+ *
1033+ * Conceptually, in the interests of understanding the
1034+ * terms that the calculus produced we can consider
1035+ * that EA and EC end up providing the lengths along
1036+ * the major axes and the hypot term ends up being an
1037+ * adjustment for the additional length along the off-axis
1038+ * angle of rotated or sheared ellipses as well as an
1039+ * adjustment for the fact that the equation below
1040+ * averages the two major axis lengths. (Notice that
1041+ * the hypot term contains a part which resolves to the
1042+ * difference of these two axis lengths in the absence
1043+ * of rotation.)
1044+ *
1045+ * In the calculus, the ratio of the EB and (EA-EC) terms
1046+ * ends up being the tangent of 2*theta where theta is
1047+ * the angle that the long axis of the ellipse makes
1048+ * with the horizontal axis. Thus, this equation is
1049+ * calculating the length of the hypotenuse of a triangle
1050+ * along that axis.
1051+ */
1052+ double hypot = Math.sqrt(EB*EB + (EA-EC)*(EA-EC));
1053+
1054+ /* sqrt omitted, compare to squared limits below. */
1055+ widthsquared = ((EA + EC + hypot)/2.0);
1056+ }
1057+ if (bs != defaultStroke) {
1058+ widthsquared *= bs.getLineWidth() * bs.getLineWidth();
1059+ }
1060+ if (widthsquared <=
1061+ (aa ? MinPenSizeAASquared : MinPenSizeSquared))
1062+ {
1063+ if (bs.getDashArray() == null) {
1064+ strokeState = STROKE_THIN;
1065+ } else {
1066+ strokeState = STROKE_THINDASHED;
1067+ }
1068+ } else {
1069+ strokeState = STROKE_WIDE;
1070+ }
1071+ }
1072+ }
1073+
1074+ /*
1075+ * Sets the Stroke in the current graphics state.
1076+ * @param s The Stroke object to be used to stroke a Path in
1077+ * the rendering process.
1078+ * @see BasicStroke
1079+ */
1080+ public void setStroke(Stroke s) {
1081+ if (s == null) {
1082+ throw new IllegalArgumentException("null Stroke");
1083+ }
1084+ int saveStrokeState = strokeState;
1085+ stroke = s;
1086+ if (s instanceof BasicStroke) {
1087+ validateBasicStroke((BasicStroke) s);
1088+ } else {
1089+ strokeState = STROKE_CUSTOM;
1090+ }
1091+ if (strokeState != saveStrokeState) {
1092+ invalidatePipe();
1093+ }
1094+ }
1095+
1096+ /**
1097+ * Sets the preferences for the rendering algorithms.
1098+ * Hint categories include controls for rendering quality and
1099+ * overall time/quality trade-off in the rendering process.
1100+ * @param hintKey The key of hint to be set. The strings are
1101+ * defined in the RenderingHints class.
1102+ * @param hintValue The value indicating preferences for the specified
1103+ * hint category. These strings are defined in the RenderingHints
1104+ * class.
1105+ * @see RenderingHints
1106+ */
1107+ public void setRenderingHint(Key hintKey, Object hintValue) {
1108+ // If we recognize the key, we must recognize the value
1109+ // otherwise throw an IllegalArgumentException
1110+ // and do not change the Hints object
1111+ // If we do not recognize the key, just pass it through
1112+ // to the Hints object untouched
1113+ if (!hintKey.isCompatibleValue(hintValue)) {
1114+ throw new IllegalArgumentException
1115+ (hintValue+" is not compatible with "+hintKey);
1116+ }
1117+ if (hintKey instanceof SunHints.Key) {
1118+ boolean stateChanged;
1119+ boolean textStateChanged = false;
1120+ boolean recognized = true;
1121+ SunHints.Key sunKey = (SunHints.Key) hintKey;
1122+ int newHint;
1123+ if (sunKey == SunHints.KEY_TEXT_ANTIALIAS_LCD_CONTRAST) {
1124+ newHint = ((Integer)hintValue).intValue();
1125+ } else {
1126+ newHint = ((SunHints.Value) hintValue).getIndex();
1127+ }
1128+ switch (sunKey.getIndex()) {
1129+ case SunHints.INTKEY_RENDERING:
1130+ stateChanged = (renderHint != newHint);
1131+ if (stateChanged) {
1132+ renderHint = newHint;
1133+ if (interpolationHint == -1) {
1134+ interpolationType =
1135+ (newHint == SunHints.INTVAL_RENDER_QUALITY
1136+ ? AffineTransformOp.TYPE_BILINEAR
1137+ : AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
1138+ }
1139+ }
1140+ break;
1141+ case SunHints.INTKEY_ANTIALIASING:
1142+ stateChanged = (antialiasHint != newHint);
1143+ antialiasHint = newHint;
1144+ if (stateChanged) {
1145+ textStateChanged =
1146+ (textAntialiasHint ==
1147+ SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT);
1148+ if (strokeState != STROKE_CUSTOM) {
1149+ validateBasicStroke((BasicStroke) stroke);
1150+ }
1151+ }
1152+ break;
1153+ case SunHints.INTKEY_TEXT_ANTIALIASING:
1154+ stateChanged = (textAntialiasHint != newHint);
1155+ textStateChanged = stateChanged;
1156+ textAntialiasHint = newHint;
1157+ break;
1158+ case SunHints.INTKEY_FRACTIONALMETRICS:
1159+ stateChanged = (fractionalMetricsHint != newHint);
1160+ textStateChanged = stateChanged;
1161+ fractionalMetricsHint = newHint;
1162+ break;
1163+ case SunHints.INTKEY_AATEXT_LCD_CONTRAST:
1164+ stateChanged = false;
1165+ /* Already have validated it is an int 100 <= newHint <= 250 */
1166+ lcdTextContrast = newHint;
1167+ break;
1168+ case SunHints.INTKEY_INTERPOLATION:
1169+ interpolationHint = newHint;
1170+ switch (newHint) {
1171+ case SunHints.INTVAL_INTERPOLATION_BICUBIC:
1172+ newHint = AffineTransformOp.TYPE_BICUBIC;
1173+ break;
1174+ case SunHints.INTVAL_INTERPOLATION_BILINEAR:
1175+ newHint = AffineTransformOp.TYPE_BILINEAR;
1176+ break;
1177+ default:
1178+ case SunHints.INTVAL_INTERPOLATION_NEAREST_NEIGHBOR:
1179+ newHint = AffineTransformOp.TYPE_NEAREST_NEIGHBOR;
1180+ break;
1181+ }
1182+ stateChanged = (interpolationType != newHint);
1183+ interpolationType = newHint;
1184+ break;
1185+ case SunHints.INTKEY_STROKE_CONTROL:
1186+ stateChanged = (strokeHint != newHint);
1187+ strokeHint = newHint;
1188+ break;
1189+ default:
1190+ recognized = false;
1191+ stateChanged = false;
1192+ break;
1193+ }
1194+ if (recognized) {
1195+ if (stateChanged) {
1196+ invalidatePipe();
1197+ if (textStateChanged) {
1198+ fontMetrics = null;
1199+ this.cachedFRC = null;
1200+ validFontInfo = false;
1201+ this.glyphVectorFontInfo = null;
1202+ }
1203+ }
1204+ if (hints != null) {
1205+ hints.put(hintKey, hintValue);
1206+ }
1207+ return;
1208+ }
1209+ }
1210+ // Nothing we recognize so none of "our state" has changed
1211+ if (hints == null) {
1212+ hints = makeHints(null);
1213+ }
1214+ hints.put(hintKey, hintValue);
1215+ }
1216+
1217+
1218+ /**
1219+ * Returns the preferences for the rendering algorithms.
1220+ * @param hintCategory The category of hint to be set. The strings
1221+ * are defined in the RenderingHints class.
1222+ * @return The preferences for rendering algorithms. The strings
1223+ * are defined in the RenderingHints class.
1224+ * @see RenderingHints
1225+ */
1226+ public Object getRenderingHint(Key hintKey) {
1227+ if (hints != null) {
1228+ return hints.get(hintKey);
1229+ }
1230+ if (!(hintKey instanceof SunHints.Key)) {
1231+ return null;
1232+ }
1233+ int keyindex = ((SunHints.Key)hintKey).getIndex();
1234+ switch (keyindex) {
1235+ case SunHints.INTKEY_RENDERING:
1236+ return SunHints.Value.get(SunHints.INTKEY_RENDERING,
1237+ renderHint);
1238+ case SunHints.INTKEY_ANTIALIASING:
1239+ return SunHints.Value.get(SunHints.INTKEY_ANTIALIASING,
1240+ antialiasHint);
1241+ case SunHints.INTKEY_TEXT_ANTIALIASING:
1242+ return SunHints.Value.get(SunHints.INTKEY_TEXT_ANTIALIASING,
1243+ textAntialiasHint);
1244+ case SunHints.INTKEY_FRACTIONALMETRICS:
1245+ return SunHints.Value.get(SunHints.INTKEY_FRACTIONALMETRICS,
1246+ fractionalMetricsHint);
1247+ case SunHints.INTKEY_AATEXT_LCD_CONTRAST:
1248+ return new Integer(lcdTextContrast);
1249+ case SunHints.INTKEY_INTERPOLATION:
1250+ switch (interpolationHint) {
1251+ case SunHints.INTVAL_INTERPOLATION_NEAREST_NEIGHBOR:
1252+ return SunHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
1253+ case SunHints.INTVAL_INTERPOLATION_BILINEAR:
1254+ return SunHints.VALUE_INTERPOLATION_BILINEAR;
1255+ case SunHints.INTVAL_INTERPOLATION_BICUBIC:
1256+ return SunHints.VALUE_INTERPOLATION_BICUBIC;
1257+ }
1258+ return null;
1259+ case SunHints.INTKEY_STROKE_CONTROL:
1260+ return SunHints.Value.get(SunHints.INTKEY_STROKE_CONTROL,
1261+ strokeHint);
1262+ }
1263+ return null;
1264+ }
1265+
1266+ /**
1267+ * Sets the preferences for the rendering algorithms.
1268+ * Hint categories include controls for rendering quality and
1269+ * overall time/quality trade-off in the rendering process.
1270+ * @param hints The rendering hints to be set
1271+ * @see RenderingHints
1272+ */
1273+ public void setRenderingHints(Map<?,?> hints) {
1274+ this.hints = null;
1275+ renderHint = SunHints.INTVAL_RENDER_DEFAULT;
1276+ antialiasHint = SunHints.INTVAL_ANTIALIAS_OFF;
1277+ textAntialiasHint = SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT;
1278+ fractionalMetricsHint = SunHints.INTVAL_FRACTIONALMETRICS_OFF;
1279+ lcdTextContrast = lcdTextContrastDefaultValue;
1280+ interpolationHint = -1;
1281+ interpolationType = AffineTransformOp.TYPE_NEAREST_NEIGHBOR;
1282+ boolean customHintPresent = false;
1283+ Iterator iter = hints.keySet().iterator();
1284+ while (iter.hasNext()) {
1285+ Object key = iter.next();
1286+ if (key == SunHints.KEY_RENDERING ||
1287+ key == SunHints.KEY_ANTIALIASING ||
1288+ key == SunHints.KEY_TEXT_ANTIALIASING ||
1289+ key == SunHints.KEY_FRACTIONALMETRICS ||
1290+ key == SunHints.KEY_TEXT_ANTIALIAS_LCD_CONTRAST ||
1291+ key == SunHints.KEY_STROKE_CONTROL ||
1292+ key == SunHints.KEY_INTERPOLATION)
1293+ {
1294+ setRenderingHint((Key) key, hints.get(key));
1295+ } else {
1296+ customHintPresent = true;
1297+ }
1298+ }
1299+ if (customHintPresent) {
1300+ this.hints = makeHints(hints);
1301+ }
1302+ invalidatePipe();
1303+ }
1304+
1305+ /**
1306+ * Adds a number of preferences for the rendering algorithms.
1307+ * Hint categories include controls for rendering quality and
1308+ * overall time/quality trade-off in the rendering process.
1309+ * @param hints The rendering hints to be set
1310+ * @see RenderingHints
1311+ */
1312+ public void addRenderingHints(Map<?,?> hints) {
1313+ boolean customHintPresent = false;
1314+ Iterator iter = hints.keySet().iterator();
1315+ while (iter.hasNext()) {
1316+ Object key = iter.next();
1317+ if (key == SunHints.KEY_RENDERING ||
1318+ key == SunHints.KEY_ANTIALIASING ||
1319+ key == SunHints.KEY_TEXT_ANTIALIASING ||
1320+ key == SunHints.KEY_FRACTIONALMETRICS ||
1321+ key == SunHints.KEY_TEXT_ANTIALIAS_LCD_CONTRAST ||
1322+ key == SunHints.KEY_STROKE_CONTROL ||
1323+ key == SunHints.KEY_INTERPOLATION)
1324+ {
1325+ setRenderingHint((Key) key, hints.get(key));
1326+ } else {
1327+ customHintPresent = true;
1328+ }
1329+ }
1330+ if (customHintPresent) {
1331+ if (this.hints == null) {
1332+ this.hints = makeHints(hints);
1333+ } else {
1334+ this.hints.putAll(hints);
1335+ }
1336+ }
1337+ }
1338+
1339+ /**
1340+ * Gets the preferences for the rendering algorithms.
1341+ * Hint categories include controls for rendering quality and
1342+ * overall time/quality trade-off in the rendering process.
1343+ * @see RenderingHints
1344+ */
1345+ public RenderingHints getRenderingHints() {
1346+ if (hints == null) {
1347+ return makeHints(null);
1348+ } else {
1349+ return (RenderingHints) hints.clone();
1350+ }
1351+ }
1352+
1353+ RenderingHints makeHints(Map hints) {
1354+ RenderingHints model = new RenderingHints(hints);
1355+ model.put(SunHints.KEY_RENDERING,
1356+ SunHints.Value.get(SunHints.INTKEY_RENDERING,
1357+ renderHint));
1358+ model.put(SunHints.KEY_ANTIALIASING,
1359+ SunHints.Value.get(SunHints.INTKEY_ANTIALIASING,
1360+ antialiasHint));
1361+ model.put(SunHints.KEY_TEXT_ANTIALIASING,
1362+ SunHints.Value.get(SunHints.INTKEY_TEXT_ANTIALIASING,
1363+ textAntialiasHint));
1364+ model.put(SunHints.KEY_FRACTIONALMETRICS,
1365+ SunHints.Value.get(SunHints.INTKEY_FRACTIONALMETRICS,
1366+ fractionalMetricsHint));
1367+ model.put(SunHints.KEY_TEXT_ANTIALIAS_LCD_CONTRAST,
1368+ Integer.valueOf(lcdTextContrast));
1369+ Object value;
1370+ switch (interpolationHint) {
1371+ case SunHints.INTVAL_INTERPOLATION_NEAREST_NEIGHBOR:
1372+ value = SunHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
1373+ break;
1374+ case SunHints.INTVAL_INTERPOLATION_BILINEAR:
1375+ value = SunHints.VALUE_INTERPOLATION_BILINEAR;
1376+ break;
1377+ case SunHints.INTVAL_INTERPOLATION_BICUBIC:
1378+ value = SunHints.VALUE_INTERPOLATION_BICUBIC;
1379+ break;
1380+ default:
1381+ value = null;
1382+ break;
1383+ }
1384+ if (value != null) {
1385+ model.put(SunHints.KEY_INTERPOLATION, value);
1386+ }
1387+ model.put(SunHints.KEY_STROKE_CONTROL,
1388+ SunHints.Value.get(SunHints.INTKEY_STROKE_CONTROL,
1389+ strokeHint));
1390+ return model;
1391+ }
1392+
1393+ /**
1394+ * Concatenates the current transform of this Graphics2D with a
1395+ * translation transformation.
1396+ * This is equivalent to calling transform(T), where T is an
1397+ * AffineTransform represented by the following matrix:
1398+ * <pre>
1399+ * [ 1 0 tx ]
1400+ * [ 0 1 ty ]
1401+ * [ 0 0 1 ]
1402+ * </pre>
1403+ */
1404+ public void translate(double tx, double ty) {
1405+ transform.translate(tx, ty);
1406+ invalidateTransform();
1407+ }
1408+
1409+ /**
1410+ * Concatenates the current transform of this Graphics2D with a
1411+ * rotation transformation.
1412+ * This is equivalent to calling transform(R), where R is an
1413+ * AffineTransform represented by the following matrix:
1414+ * <pre>
1415+ * [ cos(theta) -sin(theta) 0 ]
1416+ * [ sin(theta) cos(theta) 0 ]
1417+ * [ 0 0 1 ]
1418+ * </pre>
1419+ * Rotating with a positive angle theta rotates points on the positive
1420+ * x axis toward the positive y axis.
1421+ * @param theta The angle of rotation in radians.
1422+ */
1423+ public void rotate(double theta) {
1424+ transform.rotate(theta);
1425+ invalidateTransform();
1426+ }
1427+
1428+ /**
1429+ * Concatenates the current transform of this Graphics2D with a
1430+ * translated rotation transformation.
1431+ * This is equivalent to the following sequence of calls:
1432+ * <pre>
1433+ * translate(x, y);
1434+ * rotate(theta);
1435+ * translate(-x, -y);
1436+ * </pre>
1437+ * Rotating with a positive angle theta rotates points on the positive
1438+ * x axis toward the positive y axis.
1439+ * @param theta The angle of rotation in radians.
1440+ * @param x The x coordinate of the origin of the rotation
1441+ * @param y The x coordinate of the origin of the rotation
1442+ */
1443+ public void rotate(double theta, double x, double y) {
1444+ transform.rotate(theta, x, y);
1445+ invalidateTransform();
1446+ }
1447+
1448+ /**
1449+ * Concatenates the current transform of this Graphics2D with a
1450+ * scaling transformation.
1451+ * This is equivalent to calling transform(S), where S is an
1452+ * AffineTransform represented by the following matrix:
1453+ * <pre>
1454+ * [ sx 0 0 ]
1455+ * [ 0 sy 0 ]
1456+ * [ 0 0 1 ]
1457+ * </pre>
1458+ */
1459+ public void scale(double sx, double sy) {
1460+ transform.scale(sx, sy);
1461+ invalidateTransform();
1462+ }
1463+
1464+ /**
1465+ * Concatenates the current transform of this Graphics2D with a
1466+ * shearing transformation.
1467+ * This is equivalent to calling transform(SH), where SH is an
1468+ * AffineTransform represented by the following matrix:
1469+ * <pre>
1470+ * [ 1 shx 0 ]
1471+ * [ shy 1 0 ]
1472+ * [ 0 0 1 ]
1473+ * </pre>
1474+ * @param shx The factor by which coordinates are shifted towards the
1475+ * positive X axis direction according to their Y coordinate
1476+ * @param shy The factor by which coordinates are shifted towards the
1477+ * positive Y axis direction according to their X coordinate
1478+ */
1479+ public void shear(double shx, double shy) {
1480+ transform.shear(shx, shy);
1481+ invalidateTransform();
1482+ }
1483+
1484+ /**
1485+ * Composes a Transform object with the transform in this
1486+ * Graphics2D according to the rule last-specified-first-applied.
1487+ * If the currrent transform is Cx, the result of composition
1488+ * with Tx is a new transform Cx'. Cx' becomes the current
1489+ * transform for this Graphics2D.
1490+ * Transforming a point p by the updated transform Cx' is
1491+ * equivalent to first transforming p by Tx and then transforming
1492+ * the result by the original transform Cx. In other words,
1493+ * Cx'(p) = Cx(Tx(p)).
1494+ * A copy of the Tx is made, if necessary, so further
1495+ * modifications to Tx do not affect rendering.
1496+ * @param Tx The Transform object to be composed with the current
1497+ * transform.
1498+ * @see #setTransform
1499+ * @see AffineTransform
1500+ */
1501+ public void transform(AffineTransform xform) {
1502+ this.transform.concatenate(xform);
1503+ invalidateTransform();
1504+ }
1505+
1506+ /**
1507+ * Translate
1508+ */
1509+ public void translate(int x, int y) {
1510+ transform.translate(x, y);
1511+ if (transformState <= TRANSFORM_INT_TRANSLATE) {
1512+ transX += x;
1513+ transY += y;
1514+ transformState = (((transX | transY) == 0) ?
1515+ TRANSFORM_ISIDENT : TRANSFORM_INT_TRANSLATE);
1516+ } else {
1517+ invalidateTransform();
1518+ }
1519+ }
1520+
1521+ /**
1522+ * Sets the Transform in the current graphics state.
1523+ * @param Tx The Transform object to be used in the rendering process.
1524+ * @see #transform
1525+ * @see TransformChain
1526+ * @see AffineTransform
1527+ */
1528+ public void setTransform(AffineTransform Tx) {
1529+ if ((constrainX|constrainY) == 0) {
1530+ transform.setTransform(Tx);
1531+ } else {
1532+ transform.setToTranslation(constrainX, constrainY);
1533+ transform.concatenate(Tx);
1534+ }
1535+ invalidateTransform();
1536+ }
1537+
1538+ protected void invalidateTransform() {
1539+ int type = transform.getType();
1540+ int origTransformState = transformState;
1541+ if (type == AffineTransform.TYPE_IDENTITY) {
1542+ transformState = TRANSFORM_ISIDENT;
1543+ transX = transY = 0;
1544+ } else if (type == AffineTransform.TYPE_TRANSLATION) {
1545+ double dtx = transform.getTranslateX();
1546+ double dty = transform.getTranslateY();
1547+ transX = (int) Math.floor(dtx + 0.5);
1548+ transY = (int) Math.floor(dty + 0.5);
1549+ if (dtx == transX && dty == transY) {
1550+ transformState = TRANSFORM_INT_TRANSLATE;
1551+ } else {
1552+ transformState = TRANSFORM_ANY_TRANSLATE;
1553+ }
1554+ } else if ((type & (AffineTransform.TYPE_FLIP |
1555+ AffineTransform.TYPE_MASK_ROTATION |
1556+ AffineTransform.TYPE_GENERAL_TRANSFORM)) == 0)
1557+ {
1558+ transformState = TRANSFORM_TRANSLATESCALE;
1559+ transX = transY = 0;
1560+ } else {
1561+ transformState = TRANSFORM_GENERIC;
1562+ transX = transY = 0;
1563+ }
1564+
1565+ if (transformState >= TRANSFORM_TRANSLATESCALE ||
1566+ origTransformState >= TRANSFORM_TRANSLATESCALE)
1567+ {
1568+ /* Its only in this case that the previous or current transform
1569+ * was more than a translate that font info is invalidated
1570+ */
1571+ cachedFRC = null;
1572+ this.validFontInfo = false;
1573+ this.fontMetrics = null;
1574+ this.glyphVectorFontInfo = null;
1575+
1576+ if (transformState != origTransformState) {
1577+ invalidatePipe();
1578+ }
1579+ }
1580+ if (strokeState != STROKE_CUSTOM) {
1581+ validateBasicStroke((BasicStroke) stroke);
1582+ }
1583+ }
1584+
1585+ /**
1586+ * Returns the current Transform in the Graphics2D state.
1587+ * @see #transform
1588+ * @see #setTransform
1589+ */
1590+ public AffineTransform getTransform() {
1591+ if ((constrainX|constrainY) == 0) {
1592+ return new AffineTransform(transform);
1593+ }
1594+ AffineTransform tx =
1595+ AffineTransform.getTranslateInstance(-constrainX, -constrainY);
1596+ tx.concatenate(transform);
1597+ return tx;
1598+ }
1599+
1600+ /**
1601+ * Returns the current Transform ignoring the "constrain"
1602+ * rectangle.
1603+ */
1604+ public AffineTransform cloneTransform() {
1605+ return new AffineTransform(transform);
1606+ }
1607+
1608+ /**
1609+ * Returns the current Paint in the Graphics2D state.
1610+ * @see #setPaint
1611+ * @see java.awt.Graphics#setColor
1612+ */
1613+ public Paint getPaint() {
1614+ return paint;
1615+ }
1616+
1617+ /**
1618+ * Returns the current Composite in the Graphics2D state.
1619+ * @see #setComposite
1620+ */
1621+ public Composite getComposite() {
1622+ return composite;
1623+ }
1624+
1625+ public Color getColor() {
1626+ return foregroundColor;
1627+ }
1628+
1629+ /*
1630+ * Validate the eargb and pixel fields against the current color.
1631+ *
1632+ * The eargb field must take into account the extraAlpha
1633+ * value of an AlphaComposite. It may also take into account
1634+ * the Fsrc Porter-Duff blending function if such a function is
1635+ * a constant (see handling of Clear mode below). For instance,
1636+ * by factoring in the (Fsrc == 0) state of the Clear mode we can
1637+ * use a SrcNoEa loop just as easily as a general Alpha loop
1638+ * since the math will be the same in both cases.
1639+ *
1640+ * The pixel field will always be the best pixel data choice for
1641+ * the final result of all calculations applied to the eargb field.
1642+ *
1643+ * Note that this method is only necessary under the following
1644+ * conditions:
1645+ * (paintState <= PAINT_ALPHA_COLOR &&
1646+ * compositeState <= COMP_CUSTOM)
1647+ * though nothing bad will happen if it is run in other states.
1648+ */
1649+ final void validateColor() {
1650+ int eargb;
1651+ if (imageComp == CompositeType.Clear) {
1652+ eargb = 0;
1653+ } else {
1654+ eargb = foregroundColor.getRGB();
1655+ if (compositeState <= COMP_ALPHA &&
1656+ imageComp != CompositeType.SrcNoEa &&
1657+ imageComp != CompositeType.SrcOverNoEa)
1658+ {
1659+ AlphaComposite alphacomp = (AlphaComposite) composite;
1660+ int a = Math.round(alphacomp.getAlpha() * (eargb >>> 24));
1661+ eargb = (eargb & 0x00ffffff) | (a << 24);
1662+ }
1663+ }
1664+ this.eargb = eargb;
1665+ this.pixel = surfaceData.pixelFor(eargb);
1666+ }
1667+
1668+ public void setColor(Color color) {
1669+ if (color == null || color == paint) {
1670+ return;
1671+ }
1672+ this.paint = foregroundColor = color;
1673+ validateColor();
1674+ if ((eargb >> 24) == -1) {
1675+ if (paintState == PAINT_OPAQUECOLOR) {
1676+ return;
1677+ }
1678+ paintState = PAINT_OPAQUECOLOR;
1679+ if (imageComp == CompositeType.SrcOverNoEa) {
1680+ // special case where compState depends on opacity of paint
1681+ compositeState = COMP_ISCOPY;
1682+ }
1683+ } else {
1684+ if (paintState == PAINT_ALPHACOLOR) {
1685+ return;
1686+ }
1687+ paintState = PAINT_ALPHACOLOR;
1688+ if (imageComp == CompositeType.SrcOverNoEa) {
1689+ // special case where compState depends on opacity of paint
1690+ compositeState = COMP_ALPHA;
1691+ }
1692+ }
1693+ validFontInfo = false;
1694+ invalidatePipe();
1695+ }
1696+
1697+ /**
1698+ * Sets the background color in this context used for clearing a region.
1699+ * When Graphics2D is constructed for a component, the backgroung color is
1700+ * inherited from the component. Setting the background color in the
1701+ * Graphics2D context only affects the subsequent clearRect() calls and
1702+ * not the background color of the component. To change the background
1703+ * of the component, use appropriate methods of the component.
1704+ * @param color The background color that should be used in
1705+ * subsequent calls to clearRect().
1706+ * @see getBackground
1707+ * @see Graphics.clearRect()
1708+ */
1709+ public void setBackground(Color color) {
1710+ backgroundColor = color;
1711+ }
1712+
1713+ /**
1714+ * Returns the background color used for clearing a region.
1715+ * @see setBackground
1716+ */
1717+ public Color getBackground() {
1718+ return backgroundColor;
1719+ }
1720+
1721+ /**
1722+ * Returns the current Stroke in the Graphics2D state.
1723+ * @see setStroke
1724+ */
1725+ public Stroke getStroke() {
1726+ return stroke;
1727+ }
1728+
1729+ public Rectangle getClipBounds() {
1730+ Rectangle r;
1731+ if (clipState == CLIP_DEVICE) {
1732+ r = null;
1733+ } else if (transformState <= TRANSFORM_INT_TRANSLATE) {
1734+ if (usrClip instanceof Rectangle) {
1735+ r = new Rectangle((Rectangle) usrClip);
1736+ } else {
1737+ r = usrClip.getBounds();
1738+ }
1739+ r.translate(-transX, -transY);
1740+ } else {
1741+ r = getClip().getBounds();
1742+ }
1743+ return r;
1744+ }
1745+
1746+ public Rectangle getClipBounds(Rectangle r) {
1747+ if (clipState != CLIP_DEVICE) {
1748+ if (transformState <= TRANSFORM_INT_TRANSLATE) {
1749+ if (usrClip instanceof Rectangle) {
1750+ r.setBounds((Rectangle) usrClip);
1751+ } else {
1752+ r.setBounds(usrClip.getBounds());
1753+ }
1754+ r.translate(-transX, -transY);
1755+ } else {
1756+ r.setBounds(getClip().getBounds());
1757+ }
1758+ } else if (r == null) {
1759+ throw new NullPointerException("null rectangle parameter");
1760+ }
1761+ return r;
1762+ }
1763+
1764+ public boolean hitClip(int x, int y, int width, int height) {
1765+ if (width <= 0 || height <= 0) {
1766+ return false;
1767+ }
1768+ if (transformState > TRANSFORM_INT_TRANSLATE) {
1769+ // Note: Technically the most accurate test would be to
1770+ // raster scan the parallelogram of the transformed rectangle
1771+ // and do a span for span hit test against the clip, but for
1772+ // speed we approximate the test with a bounding box of the
1773+ // transformed rectangle. The cost of rasterizing the
1774+ // transformed rectangle is probably high enough that it is
1775+ // not worth doing so to save the caller from having to call
1776+ // a rendering method where we will end up discovering the
1777+ // same answer in about the same amount of time anyway.
1778+ // This logic breaks down if this hit test is being performed
1779+ // on the bounds of a group of shapes in which case it might
1780+ // be beneficial to be a little more accurate to avoid lots
1781+ // of subsequent rendering calls. In either case, this relaxed
1782+ // test should not be significantly less accurate than the
1783+ // optimal test for most transforms and so the conservative
1784+ // answer should not cause too much extra work.
1785+
1786+ double d[] = {
1787+ x, y,
1788+ x+width, y,
1789+ x, y+height,
1790+ x+width, y+height
1791+ };
1792+ transform.transform(d, 0, d, 0, 4);
1793+ x = (int) Math.floor(Math.min(Math.min(d[0], d[2]),
1794+ Math.min(d[4], d[6])));
1795+ y = (int) Math.floor(Math.min(Math.min(d[1], d[3]),
1796+ Math.min(d[5], d[7])));
1797+ width = (int) Math.ceil(Math.max(Math.max(d[0], d[2]),
1798+ Math.max(d[4], d[6])));
1799+ height = (int) Math.ceil(Math.max(Math.max(d[1], d[3]),
1800+ Math.max(d[5], d[7])));
1801+ } else {
1802+ x += transX;
1803+ y += transY;
1804+ width += x;
1805+ height += y;
1806+ }
1807+ if (!getCompClip().intersectsQuickCheckXYXY(x, y, width, height)) {
1808+ return false;
1809+ }
1810+ // REMIND: We could go one step further here and examine the
1811+ // non-rectangular clip shape more closely if there is one.
1812+ // Since the clip has already been rasterized, the performance
1813+ // penalty of doing the scan is probably still within the bounds
1814+ // of a good tradeoff between speed and quality of the answer.
1815+ return true;
1816+ }
1817+
1818+ protected void validateCompClip() {
1819+ int origClipState = clipState;
1820+ if (usrClip == null) {
1821+ clipState = CLIP_DEVICE;
1822+ clipRegion = devClip;
1823+ } else if (usrClip instanceof Rectangle2D) {
1824+ clipState = CLIP_RECTANGULAR;
1825+ if (usrClip instanceof Rectangle) {
1826+ clipRegion = devClip.getIntersection((Rectangle)usrClip);
1827+ } else {
1828+ clipRegion = devClip.getIntersection(usrClip.getBounds());
1829+ }
1830+ } else {
1831+ PathIterator cpi = usrClip.getPathIterator(null);
1832+ int box[] = new int[4];
1833+ ShapeSpanIterator sr = LoopPipe.getFillSSI(this);
1834+ try {
1835+ sr.setOutputArea(devClip);
1836+ sr.appendPath(cpi);
1837+ sr.getPathBox(box);
1838+ Region r = Region.getInstance(box);
1839+ r.appendSpans(sr);
1840+ clipRegion = r;
1841+ clipState =
1842+ r.isRectangular() ? CLIP_RECTANGULAR : CLIP_SHAPE;
1843+ } finally {
1844+ sr.dispose();
1845+ }
1846+ }
1847+ if (origClipState != clipState &&
1848+ (clipState == CLIP_SHAPE || origClipState == CLIP_SHAPE))
1849+ {
1850+ validFontInfo = false;
1851+ invalidatePipe();
1852+ }
1853+ }
1854+
1855+ static final int NON_RECTILINEAR_TRANSFORM_MASK =
1856+ (AffineTransform.TYPE_GENERAL_TRANSFORM |
1857+ AffineTransform.TYPE_GENERAL_ROTATION);
1858+
1859+ protected Shape transformShape(Shape s) {
1860+ if (s == null) {
1861+ return null;
1862+ }
1863+ if (transformState > TRANSFORM_INT_TRANSLATE) {
1864+ return transformShape(transform, s);
1865+ } else {
1866+ return transformShape(transX, transY, s);
1867+ }
1868+ }
1869+
1870+ public Shape untransformShape(Shape s) {
1871+ if (s == null) {
1872+ return null;
1873+ }
1874+ if (transformState > TRANSFORM_INT_TRANSLATE) {
1875+ try {
1876+ return transformShape(transform.createInverse(), s);
1877+ } catch (NoninvertibleTransformException e) {
1878+ return null;
1879+ }
1880+ } else {
1881+ return transformShape(-transX, -transY, s);
1882+ }
1883+ }
1884+
1885+ protected static Shape transformShape(int tx, int ty, Shape s) {
1886+ if (s == null) {
1887+ return null;
1888+ }
1889+
1890+ if (s instanceof Rectangle) {
1891+ Rectangle r = s.getBounds();
1892+ r.translate(tx, ty);
1893+ return r;
1894+ }
1895+ if (s instanceof Rectangle2D) {
1896+ Rectangle2D rect = (Rectangle2D) s;
1897+ return new Rectangle2D.Double(rect.getX() + tx,
1898+ rect.getY() + ty,
1899+ rect.getWidth(),
1900+ rect.getHeight());
1901+ }
1902+
1903+ if (tx == 0 && ty == 0) {
1904+ return cloneShape(s);
1905+ }
1906+
1907+ AffineTransform mat = AffineTransform.getTranslateInstance(tx, ty);
1908+ return mat.createTransformedShape(s);
1909+ }
1910+
1911+ protected static Shape transformShape(AffineTransform tx, Shape clip) {
1912+ if (clip == null) {
1913+ return null;
1914+ }
1915+
1916+ if (clip instanceof Rectangle2D &&
1917+ (tx.getType() & NON_RECTILINEAR_TRANSFORM_MASK) == 0)
1918+ {
1919+ Rectangle2D rect = (Rectangle2D) clip;
1920+ double matrix[] = new double[4];
1921+ matrix[0] = rect.getX();
1922+ matrix[1] = rect.getY();
1923+ matrix[2] = matrix[0] + rect.getWidth();
1924+ matrix[3] = matrix[1] + rect.getHeight();
1925+ tx.transform(matrix, 0, matrix, 0, 2);
1926+ rect = new Rectangle2D.Float();
1927+ rect.setFrameFromDiagonal(matrix[0], matrix[1],
1928+ matrix[2], matrix[3]);
1929+ return rect;
1930+ }
1931+
1932+ if (tx.isIdentity()) {
1933+ return cloneShape(clip);
1934+ }
1935+
1936+ return tx.createTransformedShape(clip);
1937+ }
1938+
1939+ public void clipRect(int x, int y, int w, int h) {
1940+ clip(new Rectangle(x, y, w, h));
1941+ }
1942+
1943+ public void setClip(int x, int y, int w, int h) {
1944+ setClip(new Rectangle(x, y, w, h));
1945+ }
1946+
1947+ public Shape getClip() {
1948+ return untransformShape(usrClip);
1949+ }
1950+
1951+ public void setClip(Shape sh) {
1952+ usrClip = transformShape(sh);
1953+ validateCompClip();
1954+ }
1955+
1956+ /**
1957+ * Intersects the current clip with the specified Path and sets the
1958+ * current clip to the resulting intersection. The clip is transformed
1959+ * with the current transform in the Graphics2D state before being
1960+ * intersected with the current clip. This method is used to make the
1961+ * current clip smaller. To make the clip larger, use any setClip method.
1962+ * @param p The Path to be intersected with the current clip.
1963+ */
1964+ public void clip(Shape s) {
1965+ s = transformShape(s);
1966+ if (usrClip != null) {
1967+ s = intersectShapes(usrClip, s, true, true);
1968+ }
1969+ usrClip = s;
1970+ validateCompClip();
1971+ }
1972+
1973+ public void setPaintMode() {
1974+ setComposite(AlphaComposite.SrcOver);
1975+ }
1976+
1977+ public void setXORMode(Color c) {
1978+ if (c == null) {
1979+ throw new IllegalArgumentException("null XORColor");
1980+ }
1981+ setComposite(new XORComposite(c, surfaceData));
1982+ }
1983+
1984+ Blit lastCAblit;
1985+ Composite lastCAcomp;
1986+
1987+ public void copyArea(int x, int y, int w, int h, int dx, int dy) {
1988+ try {
1989+ doCopyArea(x, y, w, h, dx, dy);
1990+ } catch (InvalidPipeException e) {
1991+ revalidateAll();
1992+ try {
1993+ doCopyArea(x, y, w, h, dx, dy);
1994+ } catch (InvalidPipeException e2) {
1995+ // Still catching the exception; we are not yet ready to
1996+ // validate the surfaceData correctly. Fail for now and
1997+ // try again next time around.
1998+ }
1999+ } finally {
2000+ surfaceData.markDirty();
2001+ }
2002+ }
2003+
2004+ private void doCopyArea(int x, int y, int w, int h, int dx, int dy) {
2005+ if (w <= 0 || h <= 0) {
2006+ return;
2007+ }
2008+ SurfaceData theData = surfaceData;
2009+ if (theData.copyArea(this, x, y, w, h, dx, dy)) {
2010+ return;
2011+ }
2012+ if (transformState >= TRANSFORM_TRANSLATESCALE) {
2013+ throw new InternalError("transformed copyArea not implemented yet");
2014+ }
2015+ // REMIND: This method does not deal with missing data from the
2016+ // source object (i.e. it does not send exposure events...)
2017+
2018+ Region clip = getCompClip();
2019+
2020+ Composite comp = composite;
2021+ if (lastCAcomp != comp) {
2022+ SurfaceType dsttype = theData.getSurfaceType();
2023+ CompositeType comptype = imageComp;
2024+ if (CompositeType.SrcOverNoEa.equals(comptype) &&
2025+ theData.getTransparency() == Transparency.OPAQUE)
2026+ {
2027+ comptype = CompositeType.SrcNoEa;
2028+ }
2029+ lastCAblit = Blit.locate(dsttype, comptype, dsttype);
2030+ lastCAcomp = comp;
2031+ }
2032+
2033+ x += transX;
2034+ y += transY;
2035+
2036+ Blit ob = lastCAblit;
2037+ if (dy == 0 && dx > 0 && dx < w) {
2038+ while (w > 0) {
2039+ int partW = Math.min(w, dx);
2040+ w -= partW;
2041+ int sx = x + w;
2042+ ob.Blit(theData, theData, comp, clip,
2043+ sx, y, sx+dx, y+dy, partW, h);
2044+ }
2045+ return;
2046+ }
2047+ if (dy > 0 && dy < h && dx > -w && dx < w) {
2048+ while (h > 0) {
2049+ int partH = Math.min(h, dy);
2050+ h -= partH;
2051+ int sy = y + h;
2052+ ob.Blit(theData, theData, comp, clip,
2053+ x, sy, x+dx, sy+dy, w, partH);
2054+ }
2055+ return;
2056+ }
2057+ ob.Blit(theData, theData, comp, clip, x, y, x+dx, y+dy, w, h);
2058+ }
2059+
2060+ /*
2061+ public void XcopyArea(int x, int y, int w, int h, int dx, int dy) {
2062+ Rectangle rect = new Rectangle(x, y, w, h);
2063+ rect = transformBounds(rect, transform);
2064+ Point2D point = new Point2D.Float(dx, dy);
2065+ Point2D root = new Point2D.Float(0, 0);
2066+ point = transform.transform(point, point);
2067+ root = transform.transform(root, root);
2068+ int fdx = (int)(point.getX()-root.getX());
2069+ int fdy = (int)(point.getY()-root.getY());
2070+
2071+ Rectangle r = getCompBounds().intersection(rect.getBounds());
2072+
2073+ if (r.isEmpty()) {
2074+ return;
2075+ }
2076+
2077+ // Begin Rasterizer for Clip Shape
2078+ boolean skipClip = true;
2079+ byte[] clipAlpha = null;
2080+
2081+ if (clipState == CLIP_SHAPE) {
2082+
2083+ int box[] = new int[4];
2084+
2085+ clipRegion.getBounds(box);
2086+ Rectangle devR = new Rectangle(box[0], box[1],
2087+ box[2] - box[0],
2088+ box[3] - box[1]);
2089+ if (!devR.isEmpty()) {
2090+ OutputManager mgr = getOutputManager();
2091+ RegionIterator ri = clipRegion.getIterator();
2092+ while (ri.nextYRange(box)) {
2093+ int spany = box[1];
2094+ int spanh = box[3] - spany;
2095+ while (ri.nextXBand(box)) {
2096+ int spanx = box[0];
2097+ int spanw = box[2] - spanx;
2098+ mgr.copyArea(this, null,
2099+ spanw, 0,
2100+ spanx, spany,
2101+ spanw, spanh,
2102+ fdx, fdy,
2103+ null);
2104+ }
2105+ }
2106+ }
2107+ return;
2108+ }
2109+ // End Rasterizer for Clip Shape
2110+
2111+ getOutputManager().copyArea(this, null,
2112+ r.width, 0,
2113+ r.x, r.y, r.width,
2114+ r.height, fdx, fdy,
2115+ null);
2116+ }
2117+ */
2118+
2119+ public void drawLine(int x1, int y1, int x2, int y2) {
2120+ try {
2121+ drawpipe.drawLine(this, x1, y1, x2, y2);
2122+ } catch (InvalidPipeException e) {
2123+ revalidateAll();
2124+ try {
2125+ drawpipe.drawLine(this, x1, y1, x2, y2);
2126+ } catch (InvalidPipeException e2) {
2127+ // Still catching the exception; we are not yet ready to
2128+ // validate the surfaceData correctly. Fail for now and
2129+ // try again next time around.
2130+ }
2131+ } finally {
2132+ surfaceData.markDirty();
2133+ }
2134+ }
2135+
2136+ public void drawRoundRect(int x, int y, int w, int h, int arcW, int arcH) {
2137+ try {
2138+ drawpipe.drawRoundRect(this, x, y, w, h, arcW, arcH);
2139+ } catch (InvalidPipeException e) {
2140+ revalidateAll();
2141+ try {
2142+ drawpipe.drawRoundRect(this, x, y, w, h, arcW, arcH);
2143+ } catch (InvalidPipeException e2) {
2144+ // Still catching the exception; we are not yet ready to
2145+ // validate the surfaceData correctly. Fail for now and
2146+ // try again next time around.
2147+ }
2148+ } finally {
2149+ surfaceData.markDirty();
2150+ }
2151+ }
2152+
2153+ public void fillRoundRect(int x, int y, int w, int h, int arcW, int arcH) {
2154+ try {
2155+ fillpipe.fillRoundRect(this, x, y, w, h, arcW, arcH);
2156+ } catch (InvalidPipeException e) {
2157+ revalidateAll();
2158+ try {
2159+ fillpipe.fillRoundRect(this, x, y, w, h, arcW, arcH);
2160+ } catch (InvalidPipeException e2) {
2161+ // Still catching the exception; we are not yet ready to
2162+ // validate the surfaceData correctly. Fail for now and
2163+ // try again next time around.
2164+ }
2165+ } finally {
2166+ surfaceData.markDirty();
2167+ }
2168+ }
2169+
2170+ public void drawOval(int x, int y, int w, int h) {
2171+ try {
2172+ drawpipe.drawOval(this, x, y, w, h);
2173+ } catch (InvalidPipeException e) {
2174+ revalidateAll();
2175+ try {
2176+ drawpipe.drawOval(this, x, y, w, h);
2177+ } catch (InvalidPipeException e2) {
2178+ // Still catching the exception; we are not yet ready to
2179+ // validate the surfaceData correctly. Fail for now and
2180+ // try again next time around.
2181+ }
2182+ } finally {
2183+ surfaceData.markDirty();
2184+ }
2185+ }
2186+
2187+ public void fillOval(int x, int y, int w, int h) {
2188+ try {
2189+ fillpipe.fillOval(this, x, y, w, h);
2190+ } catch (InvalidPipeException e) {
2191+ revalidateAll();
2192+ try {
2193+ fillpipe.fillOval(this, x, y, w, h);
2194+ } catch (InvalidPipeException e2) {
2195+ // Still catching the exception; we are not yet ready to
2196+ // validate the surfaceData correctly. Fail for now and
2197+ // try again next time around.
2198+ }
2199+ } finally {
2200+ surfaceData.markDirty();
2201+ }
2202+ }
2203+
2204+ public void drawArc(int x, int y, int w, int h,
2205+ int startAngl, int arcAngl) {
2206+ try {
2207+ drawpipe.drawArc(this, x, y, w, h, startAngl, arcAngl);
2208+ } catch (InvalidPipeException e) {
2209+ revalidateAll();
2210+ try {
2211+ drawpipe.drawArc(this, x, y, w, h, startAngl, arcAngl);
2212+ } catch (InvalidPipeException e2) {
2213+ // Still catching the exception; we are not yet ready to
2214+ // validate the surfaceData correctly. Fail for now and
2215+ // try again next time around.
2216+ }
2217+ } finally {
2218+ surfaceData.markDirty();
2219+ }
2220+ }
2221+
2222+ public void fillArc(int x, int y, int w, int h,
2223+ int startAngl, int arcAngl) {
2224+ try {
2225+ fillpipe.fillArc(this, x, y, w, h, startAngl, arcAngl);
2226+ } catch (InvalidPipeException e) {
2227+ revalidateAll();
2228+ try {
2229+ fillpipe.fillArc(this, x, y, w, h, startAngl, arcAngl);
2230+ } catch (InvalidPipeException e2) {
2231+ // Still catching the exception; we are not yet ready to
2232+ // validate the surfaceData correctly. Fail for now and
2233+ // try again next time around.
2234+ }
2235+ } finally {
2236+ surfaceData.markDirty();
2237+ }
2238+ }
2239+
2240+ public void drawPolyline(int xPoints[], int yPoints[], int nPoints) {
2241+ try {
2242+ drawpipe.drawPolyline(this, xPoints, yPoints, nPoints);
2243+ } catch (InvalidPipeException e) {
2244+ revalidateAll();
2245+ try {
2246+ drawpipe.drawPolyline(this, xPoints, yPoints, nPoints);
2247+ } catch (InvalidPipeException e2) {
2248+ // Still catching the exception; we are not yet ready to
2249+ // validate the surfaceData correctly. Fail for now and
2250+ // try again next time around.
2251+ }
2252+ } finally {
2253+ surfaceData.markDirty();
2254+ }
2255+ }
2256+
2257+ public void drawPolygon(int xPoints[], int yPoints[], int nPoints) {
2258+ try {
2259+ drawpipe.drawPolygon(this, xPoints, yPoints, nPoints);
2260+ } catch (InvalidPipeException e) {
2261+ revalidateAll();
2262+ try {
2263+ drawpipe.drawPolygon(this, xPoints, yPoints, nPoints);
2264+ } catch (InvalidPipeException e2) {
2265+ // Still catching the exception; we are not yet ready to
2266+ // validate the surfaceData correctly. Fail for now and
2267+ // try again next time around.
2268+ }
2269+ } finally {
2270+ surfaceData.markDirty();
2271+ }
2272+ }
2273+
2274+ public void fillPolygon(int xPoints[], int yPoints[], int nPoints) {
2275+ try {
2276+ fillpipe.fillPolygon(this, xPoints, yPoints, nPoints);
2277+ } catch (InvalidPipeException e) {
2278+ revalidateAll();
2279+ try {
2280+ fillpipe.fillPolygon(this, xPoints, yPoints, nPoints);
2281+ } catch (InvalidPipeException e2) {
2282+ // Still catching the exception; we are not yet ready to
2283+ // validate the surfaceData correctly. Fail for now and
2284+ // try again next time around.
2285+ }
2286+ } finally {
2287+ surfaceData.markDirty();
2288+ }
2289+ }
2290+
2291+ public void drawRect (int x, int y, int w, int h) {
2292+ try {
2293+ drawpipe.drawRect(this, x, y, w, h);
2294+ } catch (InvalidPipeException e) {
2295+ revalidateAll();
2296+ try {
2297+ drawpipe.drawRect(this, x, y, w, h);
2298+ } catch (InvalidPipeException e2) {
2299+ // Still catching the exception; we are not yet ready to
2300+ // validate the surfaceData correctly. Fail for now and
2301+ // try again next time around.
2302+ }
2303+ } finally {
2304+ surfaceData.markDirty();
2305+ }
2306+ }
2307+
2308+ public void fillRect (int x, int y, int w, int h) {
2309+ try {
2310+ fillpipe.fillRect(this, x, y, w, h);
2311+ } catch (InvalidPipeException e) {
2312+ revalidateAll();
2313+ try {
2314+ fillpipe.fillRect(this, x, y, w, h);
2315+ } catch (InvalidPipeException e2) {
2316+ // Still catching the exception; we are not yet ready to
2317+ // validate the surfaceData correctly. Fail for now and
2318+ // try again next time around.
2319+ }
2320+ } finally {
2321+ surfaceData.markDirty();
2322+ }
2323+ }
2324+
2325+ private void revalidateAll() {
2326+ try {
2327+ // REMIND: This locking needs to be done around the
2328+ // caller of this method so that the pipe stays valid
2329+ // long enough to call the new primitive.
2330+ // REMIND: No locking yet in screen SurfaceData objects!
2331+ // surfaceData.lock();
2332+ surfaceData = surfaceData.getReplacement();
2333+ if (surfaceData == null) {
2334+ surfaceData = NullSurfaceData.theInstance;
2335+ }
2336+
2337+ // this will recalculate the composite clip
2338+ setDevClip(surfaceData.getBounds());
2339+
2340+ if (paintState <= PAINT_ALPHACOLOR) {
2341+ validateColor();
2342+ }
2343+ if (composite instanceof XORComposite) {
2344+ Color c = ((XORComposite) composite).getXorColor();
2345+ setComposite(new XORComposite(c, surfaceData));
2346+ }
2347+ validatePipe();
2348+ } finally {
2349+ // REMIND: No locking yet in screen SurfaceData objects!
2350+ // surfaceData.unlock();
2351+ }
2352+ }
2353+
2354+ public void clearRect(int x, int y, int w, int h) {
2355+ // REMIND: has some "interesting" consequences if threads are
2356+ // not synchronized
2357+ Composite c = composite;
2358+ Paint p = paint;
2359+ setComposite(AlphaComposite.Src);
2360+ setColor(getBackground());
2361+ validatePipe();
2362+ fillRect(x, y, w, h);
2363+ setPaint(p);
2364+ setComposite(c);
2365+ }
2366+
2367+ /**
2368+ * Strokes the outline of a Path using the settings of the current
2369+ * graphics state. The rendering attributes applied include the
2370+ * clip, transform, paint or color, composite and stroke attributes.
2371+ * @param p The path to be drawn.
2372+ * @see #setStroke
2373+ * @see #setPaint
2374+ * @see java.awt.Graphics#setColor
2375+ * @see #transform
2376+ * @see #setTransform
2377+ * @see #clip
2378+ * @see #setClip
2379+ * @see #setComposite
2380+ */
2381+ public void draw(Shape s) {
2382+ try {
2383+ shapepipe.draw(this, s);
2384+ } catch (InvalidPipeException e) {
2385+ revalidateAll();
2386+ try {
2387+ shapepipe.draw(this, s);
2388+ } catch (InvalidPipeException e2) {
2389+ // Still catching the exception; we are not yet ready to
2390+ // validate the surfaceData correctly. Fail for now and
2391+ // try again next time around.
2392+ }
2393+ } finally {
2394+ surfaceData.markDirty();
2395+ }
2396+ }
2397+
2398+
2399+ /**
2400+ * Fills the interior of a Path using the settings of the current
2401+ * graphics state. The rendering attributes applied include the
2402+ * clip, transform, paint or color, and composite.
2403+ * @see #setPaint
2404+ * @see java.awt.Graphics#setColor
2405+ * @see #transform
2406+ * @see #setTransform
2407+ * @see #setComposite
2408+ * @see #clip
2409+ * @see #setClip
2410+ */
2411+ public void fill(Shape s) {
2412+ try {
2413+ shapepipe.fill(this, s);
2414+ } catch (InvalidPipeException e) {
2415+ revalidateAll();
2416+ try {
2417+ shapepipe.fill(this, s);
2418+ } catch (InvalidPipeException e2) {
2419+ // Still catching the exception; we are not yet ready to
2420+ // validate the surfaceData correctly. Fail for now and
2421+ // try again next time around.
2422+ }
2423+ } finally {
2424+ surfaceData.markDirty();
2425+ }
2426+ }
2427+
2428+ /**
2429+ * Returns true if the given AffineTransform is an integer
2430+ * translation.
2431+ */
2432+ private static boolean isIntegerTranslation(AffineTransform xform) {
2433+ if (xform.isIdentity()) {
2434+ return true;
2435+ }
2436+ if (xform.getType() == AffineTransform.TYPE_TRANSLATION) {
2437+ double tx = xform.getTranslateX();
2438+ double ty = xform.getTranslateY();
2439+ return (tx == (int)tx && ty == (int)ty);
2440+ }
2441+ return false;
2442+ }
2443+
2444+ /**
2445+ * Returns the index of the tile corresponding to the supplied position
2446+ * given the tile grid offset and size along the same axis.
2447+ */
2448+ private static int getTileIndex(int p, int tileGridOffset, int tileSize) {
2449+ p -= tileGridOffset;
2450+ if (p < 0) {
2451+ p += 1 - tileSize; // force round to -infinity (ceiling)
2452+ }
2453+ return p/tileSize;
2454+ }
2455+
2456+ /**
2457+ * Returns a rectangle in image coordinates that may be required
2458+ * in order to draw the given image into the given clipping region
2459+ * through a pair of AffineTransforms. In addition, horizontal and
2460+ * vertical padding factors for antialising and interpolation may
2461+ * be used.
2462+ */
2463+ private static Rectangle getImageRegion(RenderedImage img,
2464+ Region compClip,
2465+ AffineTransform transform,
2466+ AffineTransform xform,
2467+ int padX, int padY) {
2468+ Rectangle imageRect =
2469+ new Rectangle(img.getMinX(), img.getMinY(),
2470+ img.getWidth(), img.getHeight());
2471+
2472+ Rectangle result = null;
2473+ try {
2474+ double p[] = new double[8];
2475+ p[0] = p[2] = compClip.getLoX();
2476+ p[4] = p[6] = compClip.getHiX();
2477+ p[1] = p[5] = compClip.getLoY();
2478+ p[3] = p[7] = compClip.getHiY();
2479+
2480+ // Inverse transform the output bounding rect
2481+ transform.inverseTransform(p, 0, p, 0, 4);
2482+ xform.inverseTransform(p, 0, p, 0, 4);
2483+
2484+ // Determine a bounding box for the inverse transformed region
2485+ double x0,x1,y0,y1;
2486+ x0 = x1 = p[0];
2487+ y0 = y1 = p[1];
2488+
2489+ for (int i = 2; i < 8; ) {
2490+ double pt = p[i++];
2491+ if (pt < x0) {
2492+ x0 = pt;
2493+ } else if (pt > x1) {
2494+ x1 = pt;
2495+ }
2496+ pt = p[i++];
2497+ if (pt < y0) {
2498+ y0 = pt;
2499+ } else if (pt > y1) {
2500+ y1 = pt;
2501+ }
2502+ }
2503+
2504+ // This is padding for anti-aliasing and such. It may
2505+ // be more than is needed.
2506+ int x = (int)x0 - padX;
2507+ int w = (int)(x1 - x0 + 2*padX);
2508+ int y = (int)y0 - padY;
2509+ int h = (int)(y1 - y0 + 2*padY);
2510+
2511+ Rectangle clipRect = new Rectangle(x,y,w,h);
2512+ result = clipRect.intersection(imageRect);
2513+ } catch (NoninvertibleTransformException nte) {
2514+ // Worst case bounds are the bounds of the image.
2515+ result = imageRect;
2516+ }
2517+
2518+ return result;
2519+ }
2520+
2521+ /**
2522+ * Draws an image, applying a transform from image space into user space
2523+ * before drawing.
2524+ * The transformation from user space into device space is done with
2525+ * the current transform in the Graphics2D.
2526+ * The given transformation is applied to the image before the
2527+ * transform attribute in the Graphics2D state is applied.
2528+ * The rendering attributes applied include the clip, transform,
2529+ * and composite attributes. Note that the result is
2530+ * undefined, if the given transform is noninvertible.
2531+ * @param img The image to be drawn. Does nothing if img is null.
2532+ * @param xform The transformation from image space into user space.
2533+ * @see #transform
2534+ * @see #setTransform
2535+ * @see #setComposite
2536+ * @see #clip
2537+ * @see #setClip
2538+ */
2539+ public void drawRenderedImage(RenderedImage img,
2540+ AffineTransform xform) {
2541+
2542+ if (img == null) {
2543+ return;
2544+ }
2545+
2546+ // BufferedImage case: use a simple drawImage call
2547+ if (img instanceof BufferedImage) {
2548+ BufferedImage bufImg = (BufferedImage)img;
2549+ drawImage(bufImg,xform,null);
2550+ return;
2551+ }
2552+
2553+ // transformState tracks the state of transform and
2554+ // transX, transY contain the integer casts of the
2555+ // translation factors
2556+ boolean isIntegerTranslate =
2557+ (transformState <= TRANSFORM_INT_TRANSLATE) &&
2558+ isIntegerTranslation(xform);
2559+
2560+ // Include padding for interpolation/antialiasing if necessary
2561+ int pad = isIntegerTranslate ? 0 : 3;
2562+
2563+ // Determine the region of the image that may contribute to
2564+ // the clipped drawing area
2565+ Rectangle region = getImageRegion(img,
2566+ getCompClip(),
2567+ transform,
2568+ xform,
2569+ pad, pad);
2570+ if (region.width <= 0 || region.height <= 0) {
2571+ return;
2572+ }
2573+
2574+ // Attempt to optimize integer translation of tiled images.
2575+ // Although theoretically we are O.K. if the concatenation of
2576+ // the user transform and the device transform is an integer
2577+ // translation, we'll play it safe and only optimize the case
2578+ // where both are integer translations.
2579+ if (isIntegerTranslate) {
2580+ // Use optimized code
2581+ // Note that drawTranslatedRenderedImage calls copyImage
2582+ // which takes the user space to device space transform into
2583+ // account, but we need to provide the image space to user space
2584+ // translations.
2585+
2586+ drawTranslatedRenderedImage(img, region,
2587+ (int) xform.getTranslateX(),
2588+ (int) xform.getTranslateY());
2589+ return;
2590+ }
2591+
2592+ // General case: cobble the necessary region into a single Raster
2593+ Raster raster = img.getData(region);
2594+
2595+ // Make a new Raster with the same contents as raster
2596+ // but starting at (0, 0). This raster is thus in the same
2597+ // coordinate system as the SampleModel of the original raster.
2598+ WritableRaster wRaster =
2599+ Raster.createWritableRaster(raster.getSampleModel(),
2600+ raster.getDataBuffer(),
2601+ null);
2602+
2603+ // If the original raster was in a different coordinate
2604+ // system than its SampleModel, we need to perform an
2605+ // additional translation in order to get the (minX, minY)
2606+ // pixel of raster to be pixel (0, 0) of wRaster. We also
2607+ // have to have the correct width and height.
2608+ int minX = raster.getMinX();
2609+ int minY = raster.getMinY();
2610+ int width = raster.getWidth();
2611+ int height = raster.getHeight();
2612+ int px = minX - raster.getSampleModelTranslateX();
2613+ int py = minY - raster.getSampleModelTranslateY();
2614+ if (px != 0 || py != 0 || width != wRaster.getWidth() ||
2615+ height != wRaster.getHeight()) {
2616+ wRaster =
2617+ wRaster.createWritableChild(px,
2618+ py,
2619+ width,
2620+ height,
2621+ 0, 0,
2622+ null);
2623+ }
2624+
2625+ // Now we have a BufferedImage starting at (0, 0)
2626+ // with the same contents that started at (minX, minY)
2627+ // in raster. So we must draw the BufferedImage with a
2628+ // translation of (minX, minY).
2629+ AffineTransform transXform = (AffineTransform)xform.clone();
2630+ transXform.translate(minX, minY);
2631+
2632+ ColorModel cm = img.getColorModel();
2633+ BufferedImage bufImg = new BufferedImage(cm,
2634+ wRaster,
2635+ cm.isAlphaPremultiplied(),
2636+ null);
2637+ drawImage(bufImg, transXform, null);
2638+ }
2639+
2640+ /**
2641+ * Intersects <code>destRect</code> with <code>clip</code> and
2642+ * overwrites <code>destRect</code> with the result.
2643+ * Returns false if the intersection was empty, true otherwise.
2644+ */
2645+ private boolean clipTo(Rectangle destRect, Rectangle clip) {
2646+ int x1 = Math.max(destRect.x, clip.x);
2647+ int x2 = Math.min(destRect.x + destRect.width, clip.x + clip.width);
2648+ int y1 = Math.max(destRect.y, clip.y);
2649+ int y2 = Math.min(destRect.y + destRect.height, clip.y + clip.height);
2650+ if (((x2 - x1) < 0) || ((y2 - y1) < 0)) {
2651+ destRect.width = -1; // Set both just to be safe
2652+ destRect.height = -1;
2653+ return false;
2654+ } else {
2655+ destRect.x = x1;
2656+ destRect.y = y1;
2657+ destRect.width = x2 - x1;
2658+ destRect.height = y2 - y1;
2659+ return true;
2660+ }
2661+ }
2662+
2663+ /**
2664+ * Draw a portion of a RenderedImage tile-by-tile with a given
2665+ * integer image to user space translation. The user to
2666+ * device transform must also be an integer translation.
2667+ */
2668+ private void drawTranslatedRenderedImage(RenderedImage img,
2669+ Rectangle region,
2670+ int i2uTransX,
2671+ int i2uTransY) {
2672+ // Cache tile grid info
2673+ int tileGridXOffset = img.getTileGridXOffset();
2674+ int tileGridYOffset = img.getTileGridYOffset();
2675+ int tileWidth = img.getTileWidth();
2676+ int tileHeight = img.getTileHeight();
2677+
2678+ // Determine the tile index extrema in each direction
2679+ int minTileX =
2680+ getTileIndex(region.x, tileGridXOffset, tileWidth);
2681+ int minTileY =
2682+ getTileIndex(region.y, tileGridYOffset, tileHeight);
2683+ int maxTileX =
2684+ getTileIndex(region.x + region.width - 1,
2685+ tileGridXOffset, tileWidth);
2686+ int maxTileY =
2687+ getTileIndex(region.y + region.height - 1,
2688+ tileGridYOffset, tileHeight);
2689+
2690+ // Create a single ColorModel to use for all BufferedImages
2691+ ColorModel colorModel = img.getColorModel();
2692+
2693+ // Reuse the same Rectangle for each iteration
2694+ Rectangle tileRect = new Rectangle();
2695+
2696+ for (int ty = minTileY; ty <= maxTileY; ty++) {
2697+ for (int tx = minTileX; tx <= maxTileX; tx++) {
2698+ // Get the current tile.
2699+ Raster raster = img.getTile(tx, ty);
2700+
2701+ // Fill in tileRect with the tile bounds
2702+ tileRect.x = tx*tileWidth + tileGridXOffset;
2703+ tileRect.y = ty*tileHeight + tileGridYOffset;
2704+ tileRect.width = tileWidth;
2705+ tileRect.height = tileHeight;
2706+
2707+ // Clip the tile against the image bounds and
2708+ // backwards mapped clip region
2709+ // The result can't be empty
2710+ clipTo(tileRect, region);
2711+
2712+ // Create a WritableRaster containing the tile
2713+ WritableRaster wRaster = null;
2714+ if (raster instanceof WritableRaster) {
2715+ wRaster = (WritableRaster)raster;
2716+ } else {
2717+ // Create a WritableRaster in the same coordinate system
2718+ // as the original raster.
2719+ wRaster =
2720+ Raster.createWritableRaster(raster.getSampleModel(),
2721+ raster.getDataBuffer(),
2722+ null);
2723+ }
2724+
2725+ // Translate wRaster to start at (0, 0) and to contain
2726+ // only the relevent portion of the tile
2727+ wRaster = wRaster.createWritableChild(tileRect.x, tileRect.y,
2728+ tileRect.width,
2729+ tileRect.height,
2730+ 0, 0,
2731+ null);
2732+
2733+ // Wrap wRaster in a BufferedImage
2734+ BufferedImage bufImg =
2735+ new BufferedImage(colorModel,
2736+ wRaster,
2737+ colorModel.isAlphaPremultiplied(),
2738+ null);
2739+ // Now we have a BufferedImage starting at (0, 0) that
2740+ // represents data from a Raster starting at
2741+ // (tileRect.x, tileRect.y). Additionally, it needs
2742+ // to be translated by (i2uTransX, i2uTransY). We call
2743+ // copyImage to draw just the region of interest
2744+ // without needing to create a child image.
2745+ copyImage(bufImg, tileRect.x + i2uTransX,
2746+ tileRect.y + i2uTransY, 0, 0, tileRect.width,
2747+ tileRect.height, null, null);
2748+ }
2749+ }
2750+ }
2751+
2752+ public void drawRenderableImage(RenderableImage img,
2753+ AffineTransform xform) {
2754+
2755+ if (img == null) {
2756+ return;
2757+ }
2758+
2759+ AffineTransform pipeTransform = transform;
2760+ AffineTransform concatTransform = new AffineTransform(xform);
2761+ concatTransform.concatenate(pipeTransform);
2762+ AffineTransform reverseTransform;
2763+
2764+ RenderContext rc = new RenderContext(concatTransform);
2765+
2766+ try {
2767+ reverseTransform = pipeTransform.createInverse();
2768+ } catch (NoninvertibleTransformException nte) {
2769+ rc = new RenderContext(pipeTransform);
2770+ reverseTransform = new AffineTransform();
2771+ }
2772+
2773+ RenderedImage rendering = img.createRendering(rc);
2774+ drawRenderedImage(rendering,reverseTransform);
2775+ }
2776+
2777+
2778+
2779+ /*
2780+ * Transform the bounding box of the BufferedImage
2781+ */
2782+ protected Rectangle transformBounds(Rectangle rect,
2783+ AffineTransform tx) {
2784+ if (tx.isIdentity()) {
2785+ return rect;
2786+ }
2787+
2788+ Shape s = transformShape(tx, rect);
2789+ return s.getBounds();
2790+ }
2791+
2792+ // text rendering methods
2793+ public void drawString(String str, int x, int y) {
2794+ if (str == null) {
2795+ throw new NullPointerException("String is null");
2796+ }
2797+
2798+ if (font.hasLayoutAttributes()) {
2799+ if (str.length() == 0) {
2800+ return;
2801+ }
2802+ new TextLayout(str, font, getFontRenderContext()).draw(this, x, y);
2803+ return;
2804+ }
2805+
2806+ try {
2807+ textpipe.drawString(this, str, x, y);
2808+ } catch (InvalidPipeException e) {
2809+ revalidateAll();
2810+ try {
2811+ textpipe.drawString(this, str, x, y);
2812+ } catch (InvalidPipeException e2) {
2813+ // Still catching the exception; we are not yet ready to
2814+ // validate the surfaceData correctly. Fail for now and
2815+ // try again next time around.
2816+ }
2817+ } finally {
2818+ surfaceData.markDirty();
2819+ }
2820+ }
2821+
2822+ public void drawString(String str, float x, float y) {
2823+ if (str == null) {
2824+ throw new NullPointerException("String is null");
2825+ }
2826+
2827+ if (font.hasLayoutAttributes()) {
2828+ if (str.length() == 0) {
2829+ return;
2830+ }
2831+ new TextLayout(str, font, getFontRenderContext()).draw(this, x, y);
2832+ return;
2833+ }
2834+
2835+ try {
2836+ textpipe.drawString(this, str, x, y);
2837+ } catch (InvalidPipeException e) {
2838+ revalidateAll();
2839+ try {
2840+ textpipe.drawString(this, str, x, y);
2841+ } catch (InvalidPipeException e2) {
2842+ // Still catching the exception; we are not yet ready to
2843+ // validate the surfaceData correctly. Fail for now and
2844+ // try again next time around.
2845+ }
2846+ } finally {
2847+ surfaceData.markDirty();
2848+ }
2849+ }
2850+
2851+ public void drawString(AttributedCharacterIterator iterator,
2852+ int x, int y) {
2853+ if (iterator == null) {
2854+ throw new NullPointerException("AttributedCharacterIterator is null");
2855+ }
2856+ if (iterator.getBeginIndex() == iterator.getEndIndex()) {
2857+ return; /* nothing to draw */
2858+ }
2859+ TextLayout tl = new TextLayout(iterator, getFontRenderContext());
2860+ tl.draw(this, (float) x, (float) y);
2861+ }
2862+
2863+ public void drawString(AttributedCharacterIterator iterator,
2864+ float x, float y) {
2865+ if (iterator == null) {
2866+ throw new NullPointerException("AttributedCharacterIterator is null");
2867+ }
2868+ if (iterator.getBeginIndex() == iterator.getEndIndex()) {
2869+ return; /* nothing to draw */
2870+ }
2871+ TextLayout tl = new TextLayout(iterator, getFontRenderContext());
2872+ tl.draw(this, x, y);
2873+ }
2874+
2875+ public void drawGlyphVector(GlyphVector gv, float x, float y)
2876+ {
2877+ if (gv == null) {
2878+ throw new NullPointerException("GlyphVector is null");
2879+ }
2880+
2881+ try {
2882+ textpipe.drawGlyphVector(this, gv, x, y);
2883+ } catch (InvalidPipeException e) {
2884+ revalidateAll();
2885+ try {
2886+ textpipe.drawGlyphVector(this, gv, x, y);
2887+ } catch (InvalidPipeException e2) {
2888+ // Still catching the exception; we are not yet ready to
2889+ // validate the surfaceData correctly. Fail for now and
2890+ // try again next time around.
2891+ }
2892+ } finally {
2893+ surfaceData.markDirty();
2894+ }
2895+ }
2896+
2897+ public void drawChars(char data[], int offset, int length, int x, int y) {
2898+
2899+ if (data == null) {
2900+ throw new NullPointerException("char data is null");
2901+ }
2902+ if (offset < 0 || length < 0 || offset + length > data.length) {
2903+ throw new ArrayIndexOutOfBoundsException("bad offset/length");
2904+ }
2905+ if (font.hasLayoutAttributes()) {
2906+ if (data.length == 0) {
2907+ return;
2908+ }
2909+ new TextLayout(new String(data, offset, length),
2910+ font, getFontRenderContext()).draw(this, x, y);
2911+ return;
2912+ }
2913+
2914+ try {
2915+ textpipe.drawChars(this, data, offset, length, x, y);
2916+ } catch (InvalidPipeException e) {
2917+ revalidateAll();
2918+ try {
2919+ textpipe.drawChars(this, data, offset, length, x, y);
2920+ } catch (InvalidPipeException e2) {
2921+ // Still catching the exception; we are not yet ready to
2922+ // validate the surfaceData correctly. Fail for now and
2923+ // try again next time around.
2924+ }
2925+ } finally {
2926+ surfaceData.markDirty();
2927+ }
2928+ }
2929+
2930+ public void drawBytes(byte data[], int offset, int length, int x, int y) {
2931+ if (data == null) {
2932+ throw new NullPointerException("byte data is null");
2933+ }
2934+ if (offset < 0 || length < 0 || offset + length > data.length) {
2935+ throw new ArrayIndexOutOfBoundsException("bad offset/length");
2936+ }
2937+ /* Byte data is interpreted as 8-bit ASCII. Re-use drawChars loops */
2938+ char chData[] = new char[length];
2939+ for (int i = length; i-- > 0; ) {
2940+ chData[i] = (char)(data[i+offset] & 0xff);
2941+ }
2942+ if (font.hasLayoutAttributes()) {
2943+ if (data.length == 0) {
2944+ return;
2945+ }
2946+ new TextLayout(new String(chData),
2947+ font, getFontRenderContext()).draw(this, x, y);
2948+ return;
2949+ }
2950+
2951+ try {
2952+ textpipe.drawChars(this, chData, 0, length, x, y);
2953+ } catch (InvalidPipeException e) {
2954+ revalidateAll();
2955+ try {
2956+ textpipe.drawChars(this, chData, 0, length, x, y);
2957+ } catch (InvalidPipeException e2) {
2958+ // Still catching the exception; we are not yet ready to
2959+ // validate the surfaceData correctly. Fail for now and
2960+ // try again next time around.
2961+ }
2962+ } finally {
2963+ surfaceData.markDirty();
2964+ }
2965+ }
2966+// end of text rendering methods
2967+
2968+ /**
2969+ * Draws an image scaled to x,y,w,h in nonblocking mode with a
2970+ * callback object.
2971+ */
2972+ public boolean drawImage(Image img, int x, int y, int width, int height,
2973+ ImageObserver observer) {
2974+ return drawImage(img, x, y, width, height, null, observer);
2975+ }
2976+
2977+ /**
2978+ * Not part of the advertised API but a useful utility method
2979+ * to call internally. This is for the case where we are
2980+ * drawing to/from given coordinates using a given width/height,
2981+ * but we guarantee that the weidth/height of the src and dest
2982+ * areas are equal (no scale needed).
2983+ */
2984+ public boolean copyImage(Image img, int dx, int dy, int sx, int sy,
2985+ int width, int height, Color bgcolor,
2986+ ImageObserver observer) {
2987+ try {
2988+ return imagepipe.copyImage(this, img, dx, dy, sx, sy,
2989+ width, height, bgcolor, observer);
2990+ } catch (InvalidPipeException e) {
2991+ revalidateAll();
2992+ try {
2993+ return imagepipe.copyImage(this, img, dx, dy, sx, sy,
2994+ width, height, bgcolor, observer);
2995+ } catch (InvalidPipeException e2) {
2996+ // Still catching the exception; we are not yet ready to
2997+ // validate the surfaceData correctly. Fail for now and
2998+ // try again next time around.
2999+ return false;
3000+ }
3001+ } finally {
3002+ surfaceData.markDirty();
3003+ }
3004+ }
3005+
3006+ /**
3007+ * Draws an image scaled to x,y,w,h in nonblocking mode with a
3008+ * solid background color and a callback object.
3009+ */
3010+ public boolean drawImage(Image img, int x, int y, int width, int height,
3011+ Color bg, ImageObserver observer) {
3012+
3013+ if (img == null) {
3014+ return true;
3015+ }
3016+
3017+ if ((width == 0) || (height == 0)) {
3018+ return true;
3019+ }
3020+ if (width == img.getWidth(null) && height == img.getHeight(null)) {
3021+ return copyImage(img, x, y, 0, 0, width, height, bg, observer);
3022+ }
3023+
3024+ try {
3025+ return imagepipe.scaleImage(this, img, x, y, width, height,
3026+ bg, observer);
3027+ } catch (InvalidPipeException e) {
3028+ revalidateAll();
3029+ try {
3030+ return imagepipe.scaleImage(this, img, x, y, width, height,
3031+ bg, observer);
3032+ } catch (InvalidPipeException e2) {
3033+ // Still catching the exception; we are not yet ready to
3034+ // validate the surfaceData correctly. Fail for now and
3035+ // try again next time around.
3036+ return false;
3037+ }
3038+ } finally {
3039+ surfaceData.markDirty();
3040+ }
3041+ }
3042+
3043+ /**
3044+ * Draws an image at x,y in nonblocking mode.
3045+ */
3046+ public boolean drawImage(Image img, int x, int y, ImageObserver observer) {
3047+ return drawImage(img, x, y, null, observer);
3048+ }
3049+
3050+ /**
3051+ * Draws an image at x,y in nonblocking mode with a solid background
3052+ * color and a callback object.
3053+ */
3054+ public boolean drawImage(Image img, int x, int y, Color bg,
3055+ ImageObserver observer) {
3056+
3057+ if (img == null) {
3058+ return true;
3059+ }
3060+
3061+ try {
3062+ return imagepipe.copyImage(this, img, x, y, bg, observer);
3063+ } catch (InvalidPipeException e) {
3064+ revalidateAll();
3065+ try {
3066+ return imagepipe.copyImage(this, img, x, y, bg, observer);
3067+ } catch (InvalidPipeException e2) {
3068+ // Still catching the exception; we are not yet ready to
3069+ // validate the surfaceData correctly. Fail for now and
3070+ // try again next time around.
3071+ return false;
3072+ }
3073+ } finally {
3074+ surfaceData.markDirty();
3075+ }
3076+ }
3077+
3078+ /**
3079+ * Draws a subrectangle of an image scaled to a destination rectangle
3080+ * in nonblocking mode with a callback object.
3081+ */
3082+ public boolean drawImage(Image img,
3083+ int dx1, int dy1, int dx2, int dy2,
3084+ int sx1, int sy1, int sx2, int sy2,
3085+ ImageObserver observer) {
3086+ return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null,
3087+ observer);
3088+ }
3089+
3090+ /**
3091+ * Draws a subrectangle of an image scaled to a destination rectangle in
3092+ * nonblocking mode with a solid background color and a callback object.
3093+ */
3094+ public boolean drawImage(Image img,
3095+ int dx1, int dy1, int dx2, int dy2,
3096+ int sx1, int sy1, int sx2, int sy2,
3097+ Color bgcolor, ImageObserver observer) {
3098+
3099+ if (img == null) {
3100+ return true;
3101+ }
3102+
3103+ if (dx1 == dx2 || dy1 == dy2 ||
3104+ sx1 == sx2 || sy1 == sy2)
3105+ {
3106+ return true;
3107+ }
3108+
3109+ if (((sx2 - sx1) == (dx2 - dx1)) &&
3110+ ((sy2 - sy1) == (dy2 - dy1)))
3111+ {
3112+ // Not a scale - forward it to a copy routine
3113+ int srcX, srcY, dstX, dstY, width, height;
3114+ if (sx2 > sx1) {
3115+ width = sx2 - sx1;
3116+ srcX = sx1;
3117+ dstX = dx1;
3118+ } else {
3119+ width = sx1 - sx2;
3120+ srcX = sx2;
3121+ dstX = dx2;
3122+ }
3123+ if (sy2 > sy1) {
3124+ height = sy2-sy1;
3125+ srcY = sy1;
3126+ dstY = dy1;
3127+ } else {
3128+ height = sy1-sy2;
3129+ srcY = sy2;
3130+ dstY = dy2;
3131+ }
3132+ return copyImage(img, dstX, dstY, srcX, srcY,
3133+ width, height, bgcolor, observer);
3134+ }
3135+
3136+ try {
3137+ return imagepipe.scaleImage(this, img, dx1, dy1, dx2, dy2,
3138+ sx1, sy1, sx2, sy2, bgcolor,
3139+ observer);
3140+ } catch (InvalidPipeException e) {
3141+ revalidateAll();
3142+ try {
3143+ return imagepipe.scaleImage(this, img, dx1, dy1, dx2, dy2,
3144+ sx1, sy1, sx2, sy2, bgcolor,
3145+ observer);
3146+ } catch (InvalidPipeException e2) {
3147+ // Still catching the exception; we are not yet ready to
3148+ // validate the surfaceData correctly. Fail for now and
3149+ // try again next time around.
3150+ return false;
3151+ }
3152+ } finally {
3153+ surfaceData.markDirty();
3154+ }
3155+ }
3156+
3157+ /**
3158+ * Draw an image, applying a transform from image space into user space
3159+ * before drawing.
3160+ * The transformation from user space into device space is done with
3161+ * the current transform in the Graphics2D.
3162+ * The given transformation is applied to the image before the
3163+ * transform attribute in the Graphics2D state is applied.
3164+ * The rendering attributes applied include the clip, transform,
3165+ * paint or color and composite attributes. Note that the result is
3166+ * undefined, if the given transform is non-invertible.
3167+ * @param img The image to be drawn.
3168+ * @param xform The transformation from image space into user space.
3169+ * @param observer The image observer to be notified on the image producing
3170+ * progress.
3171+ * @see #transform
3172+ * @see #setComposite
3173+ * @see #setClip
3174+ */
3175+ public boolean drawImage(Image img,
3176+ AffineTransform xform,
3177+ ImageObserver observer) {
3178+
3179+ if (img == null) {
3180+ return true;
3181+ }
3182+
3183+ if (xform == null || xform.isIdentity()) {
3184+ return drawImage(img, 0, 0, null, observer);
3185+ }
3186+
3187+ try {
3188+ return imagepipe.transformImage(this, img, xform, observer);
3189+ } catch (InvalidPipeException e) {
3190+ revalidateAll();
3191+ try {
3192+ return imagepipe.transformImage(this, img, xform, observer);
3193+ } catch (InvalidPipeException e2) {
3194+ // Still catching the exception; we are not yet ready to
3195+ // validate the surfaceData correctly. Fail for now and
3196+ // try again next time around.
3197+ return false;
3198+ }
3199+ } finally {
3200+ surfaceData.markDirty();
3201+ }
3202+ }
3203+
3204+ public void drawImage(BufferedImage bImg,
3205+ BufferedImageOp op,
3206+ int x,
3207+ int y) {
3208+
3209+ if (bImg == null) {
3210+ return;
3211+ }
3212+
3213+ try {
3214+ imagepipe.transformImage(this, bImg, op, x, y);
3215+ } catch (InvalidPipeException e) {
3216+ revalidateAll();
3217+ try {
3218+ imagepipe.transformImage(this, bImg, op, x, y);
3219+ } catch (InvalidPipeException e2) {
3220+ // Still catching the exception; we are not yet ready to
3221+ // validate the surfaceData correctly. Fail for now and
3222+ // try again next time around.
3223+ }
3224+ } finally {
3225+ surfaceData.markDirty();
3226+ }
3227+ }
3228+
3229+ /**
3230+ * Get the rendering context of the font
3231+ * within this Graphics2D context.
3232+ */
3233+ public FontRenderContext getFontRenderContext() {
3234+ if (cachedFRC == null) {
3235+ int aahint = textAntialiasHint;
3236+ if (aahint == SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT &&
3237+ antialiasHint == SunHints.INTVAL_ANTIALIAS_ON) {
3238+ aahint = SunHints.INTVAL_TEXT_ANTIALIAS_ON;
3239+ }
3240+ // Translation components should be excluded from the FRC transform
3241+ AffineTransform tx = null;
3242+ if (transformState >= TRANSFORM_TRANSLATESCALE) {
3243+ if (transform.getTranslateX() == 0 &&
3244+ transform.getTranslateY() == 0) {
3245+ tx = transform;
3246+ } else {
3247+ tx = new AffineTransform(transform.getScaleX(),
3248+ transform.getShearY(),
3249+ transform.getShearX(),
3250+ transform.getScaleY(),
3251+ 0, 0);
3252+ }
3253+ }
3254+ cachedFRC = new FontRenderContext(tx,
3255+ SunHints.Value.get(SunHints.INTKEY_TEXT_ANTIALIASING, aahint),
3256+ SunHints.Value.get(SunHints.INTKEY_FRACTIONALMETRICS,
3257+ fractionalMetricsHint));
3258+ }
3259+ return cachedFRC;
3260+ }
3261+ private FontRenderContext cachedFRC;
3262+
3263+ /**
3264+ * This object has no resources to dispose of per se, but the
3265+ * doc comments for the base method in java.awt.Graphics imply
3266+ * that this object will not be useable after it is disposed.
3267+ * So, we sabotage the object to prevent further use to prevent
3268+ * developers from relying on behavior that may not work on
3269+ * other, less forgiving, VMs that really need to dispose of
3270+ * resources.
3271+ */
3272+ public void dispose() {
3273+ surfaceData = NullSurfaceData.theInstance;
3274+ invalidatePipe();
3275+ }
3276+
3277+ /**
3278+ * Graphics has a finalize method that automatically calls dispose()
3279+ * for subclasses. For SunGraphics2D we do not need to be finalized
3280+ * so that method simply causes us to be enqueued on the Finalizer
3281+ * queues for no good reason. Unfortunately, that method and
3282+ * implementation are now considered part of the public contract
3283+ * of that base class so we can not remove or gut the method.
3284+ * We override it here with an empty method and the VM is smart
3285+ * enough to know that if our override is empty then it should not
3286+ * mark us as finalizeable.
3287+ */
3288+ public void finalize() {
3289+ // DO NOT REMOVE THIS METHOD
3290+ }
3291+
3292+ /**
3293+ * Returns destination that this Graphics renders to. This could be
3294+ * either an Image or a Component; subclasses of SurfaceData are
3295+ * responsible for returning the appropriate object.
3296+ */
3297+ public Object getDestination() {
3298+ return surfaceData.getDestination();
3299+ }
3300+
3301+ /**
3302+ * {@inheritDoc}
3303+ *
3304+ * @see sun.java2d.DestSurfaceProvider#getDestSurface
3305+ */
3306+ @Override
3307+ public Surface getDestSurface() {
3308+ return surfaceData;
3309+ }
3310+}
java/pkg/sun/java2d/SunGraphicsEnvironment$1.class+0−0

Binary file not shown.

java/pkg/sun/java2d/SunGraphicsEnvironment.class+0−0

Binary file not shown.

java/pkg/sun/java2d/SunGraphicsEnvironment.java+337−0
@@ -0,0 +1,337 @@
1+/*
2+ * Copyright (c) 1997, 2011, 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+
26+package sun.java2d;
27+
28+import java.awt.Color;
29+import java.awt.Font;
30+import java.awt.Graphics2D;
31+import java.awt.GraphicsConfiguration;
32+import java.awt.GraphicsDevice;
33+import java.awt.GraphicsEnvironment;
34+import java.awt.Insets;
35+import java.awt.Rectangle;
36+import java.awt.Toolkit;
37+import java.awt.font.TextAttribute;
38+import java.awt.image.BufferedImage;
39+import java.awt.peer.ComponentPeer;
40+import java.io.BufferedReader;
41+import java.io.File;
42+import java.io.FileInputStream;
43+import java.io.FilenameFilter;
44+import java.io.InputStreamReader;
45+import java.io.IOException;
46+import java.text.AttributedCharacterIterator;
47+import java.util.ArrayList;
48+import java.util.HashSet;
49+import java.util.Iterator;
50+import java.util.Locale;
51+import java.util.Map;
52+import java.util.NoSuchElementException;
53+import java.util.Set;
54+import java.util.StringTokenizer;
55+import java.util.TreeMap;
56+import java.util.Vector;
57+import java.util.concurrent.ConcurrentHashMap;
58+import sun.awt.AppContext;
59+import sun.awt.DisplayChangedListener;
60+import sun.awt.FontConfiguration;
61+import sun.awt.SunDisplayChanger;
62+import sun.font.CompositeFontDescriptor;
63+import sun.font.Font2D;
64+import sun.font.FontManager;
65+import sun.font.FontManagerFactory;
66+import sun.font.FontManagerForSGE;
67+import sun.font.NativeFont;
68+
69+/**
70+ * This is an implementation of a GraphicsEnvironment object for the
71+ * default local GraphicsEnvironment.
72+ *
73+ * @see GraphicsDevice
74+ * @see GraphicsConfiguration
75+ */
76+public abstract class SunGraphicsEnvironment extends GraphicsEnvironment
77+ implements DisplayChangedListener {
78+
79+ public static boolean isOpenSolaris;
80+ private static Font defaultFont;
81+
82+ public SunGraphicsEnvironment() {
83+ java.security.AccessController.doPrivileged(
84+ new java.security.PrivilegedAction() {
85+ public Object run() {
86+ String version = System.getProperty("os.version", "0.0");
87+ try {
88+ float ver = Float.parseFloat(version);
89+ if (ver > 5.10f) {
90+ File f = new File("/etc/release");
91+ FileInputStream fis = new FileInputStream(f);
92+ InputStreamReader isr
93+ = new InputStreamReader(fis, "ISO-8859-1");
94+ BufferedReader br = new BufferedReader(isr);
95+ String line = br.readLine();
96+ if (line.indexOf("OpenSolaris") >= 0) {
97+ isOpenSolaris = true;
98+ } else {
99+ /* We are using isOpenSolaris as meaning
100+ * we know the Solaris commercial fonts aren't
101+ * present. "Solaris Next" (03/10) did not
102+ * include these even though its was not
103+ * OpenSolaris. Need to revisit how this is
104+ * handled but for now as in 6ux, we'll use
105+ * the test for a standard font resource as
106+ * being an indicator as to whether we need
107+ * to treat this as OpenSolaris from a font
108+ * config perspective.
109+ */
110+ String courierNew =
111+ "/usr/openwin/lib/X11/fonts/TrueType/CourierNew.ttf";
112+ File courierFile = new File(courierNew);
113+ isOpenSolaris = !courierFile.exists();
114+ }
115+ fis.close();
116+ }
117+ } catch (Exception e) {
118+ }
119+
120+ /* Establish the default font to be used by SG2D etc */
121+ defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
122+
123+ return null;
124+ }
125+ });
126+ }
127+
128+ protected GraphicsDevice[] screens;
129+
130+ /**
131+ * Returns an array of all of the screen devices.
132+ */
133+ public synchronized GraphicsDevice[] getScreenDevices() {
134+ GraphicsDevice[] ret = screens;
135+ if (ret == null) {
136+ int num = getNumScreens();
137+ ret = new GraphicsDevice[num];
138+ for (int i = 0; i < num; i++) {
139+ ret[i] = makeScreenDevice(i);
140+ }
141+ screens = ret;
142+ }
143+ return ret;
144+ }
145+
146+ /**
147+ * Returns the number of screen devices of this graphics environment.
148+ *
149+ * @return the number of screen devices of this graphics environment
150+ */
151+ protected abstract int getNumScreens();
152+
153+ /**
154+ * Create and return the screen device with the specified number. The
155+ * device with number <code>0</code> will be the default device (returned
156+ * by {@link #getDefaultScreenDevice()}.
157+ *
158+ * @param screennum the number of the screen to create
159+ *
160+ * @return the created screen device
161+ */
162+ protected abstract GraphicsDevice makeScreenDevice(int screennum);
163+
164+ /**
165+ * Returns the default screen graphics device.
166+ */
167+ public GraphicsDevice getDefaultScreenDevice() {
168+ return getScreenDevices()[0];
169+ }
170+
171+ /**
172+ * Returns a Graphics2D object for rendering into the
173+ * given BufferedImage.
174+ * @throws NullPointerException if BufferedImage argument is null
175+ */
176+ public Graphics2D createGraphics(BufferedImage img) {
177+ if (img == null) {
178+ throw new NullPointerException("BufferedImage cannot be null");
179+ }
180+ SurfaceData sd = SurfaceData.getPrimarySurfaceData(img);
181+ return new SunGraphics2D(sd, Color.white, Color.black, defaultFont);
182+ }
183+
184+ public static FontManagerForSGE getFontManagerForSGE() {
185+ FontManager fm = FontManagerFactory.getInstance();
186+ return (FontManagerForSGE) fm;
187+ }
188+
189+ /* Modifies the behaviour of a subsequent call to preferLocaleFonts()
190+ * to use Mincho instead of Gothic for dialoginput in JA locales
191+ * on windows. Not needed on other platforms.
192+ *
193+ * DO NOT MOVE OR RENAME OR OTHERWISE ALTER THIS METHOD.
194+ * ITS USED BY SOME NON-JRE INTERNAL CODE.
195+ */
196+ public static void useAlternateFontforJALocales() {
197+ getFontManagerForSGE().useAlternateFontforJALocales();
198+ }
199+
200+ /**
201+ * Returns all fonts available in this environment.
202+ */
203+ public Font[] getAllFonts() {
204+ FontManagerForSGE fm = getFontManagerForSGE();
205+ Font[] installedFonts = fm.getAllInstalledFonts();
206+ Font[] created = fm.getCreatedFonts();
207+ if (created == null || created.length == 0) {
208+ return installedFonts;
209+ } else {
210+ int newlen = installedFonts.length + created.length;
211+ Font [] fonts = java.util.Arrays.copyOf(installedFonts, newlen);
212+ System.arraycopy(created, 0, fonts,
213+ installedFonts.length, created.length);
214+ return fonts;
215+ }
216+ }
217+
218+ public String[] getAvailableFontFamilyNames(Locale requestedLocale) {
219+ FontManagerForSGE fm = getFontManagerForSGE();
220+ String[] installed = fm.getInstalledFontFamilyNames(requestedLocale);
221+ /* Use a new TreeMap as used in getInstalledFontFamilyNames
222+ * and insert all the keys in lower case, so that the sort order
223+ * is the same as the installed families. This preserves historical
224+ * behaviour and inserts new families in the right place.
225+ * It would have been marginally more efficient to directly obtain
226+ * the tree map and just insert new entries, but not so much as
227+ * to justify the extra internal interface.
228+ */
229+ TreeMap<String, String> map = fm.getCreatedFontFamilyNames();
230+ if (map == null || map.size() == 0) {
231+ return installed;
232+ } else {
233+ for (int i=0; i<installed.length; i++) {
234+ map.put(installed[i].toLowerCase(requestedLocale),
235+ installed[i]);
236+ }
237+ String[] retval = new String[map.size()];
238+ Object [] keyNames = map.keySet().toArray();
239+ for (int i=0; i < keyNames.length; i++) {
240+ retval[i] = (String)map.get(keyNames[i]);
241+ }
242+ return retval;
243+ }
244+ }
245+
246+ public String[] getAvailableFontFamilyNames() {
247+ return getAvailableFontFamilyNames(Locale.getDefault());
248+ }
249+
250+ /**
251+ * Return the bounds of a GraphicsDevice, less its screen insets.
252+ * See also java.awt.GraphicsEnvironment.getUsableBounds();
253+ */
254+ public static Rectangle getUsableBounds(GraphicsDevice gd) {
255+ GraphicsConfiguration gc = gd.getDefaultConfiguration();
256+ Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
257+ Rectangle usableBounds = gc.getBounds();
258+
259+ usableBounds.x += insets.left;
260+ usableBounds.y += insets.top;
261+ usableBounds.width -= (insets.left + insets.right);
262+ usableBounds.height -= (insets.top + insets.bottom);
263+
264+ return usableBounds;
265+ }
266+
267+ /**
268+ * From the DisplayChangedListener interface; called
269+ * when the display mode has been changed.
270+ */
271+ public void displayChanged() {
272+ // notify screens in device array to do display update stuff
273+ for (GraphicsDevice gd : getScreenDevices()) {
274+ if (gd instanceof DisplayChangedListener) {
275+ ((DisplayChangedListener) gd).displayChanged();
276+ }
277+ }
278+
279+ // notify SunDisplayChanger list (e.g. VolatileSurfaceManagers and
280+ // SurfaceDataProxies) about the display change event
281+ displayChanger.notifyListeners();
282+ }
283+
284+ /**
285+ * Part of the DisplayChangedListener interface:
286+ * propagate this event to listeners
287+ */
288+ public void paletteChanged() {
289+ displayChanger.notifyPaletteChanged();
290+ }
291+
292+ /**
293+ * Returns true when the display is local, false for remote displays.
294+ *
295+ * @return true when the display is local, false for remote displays
296+ */
297+ public abstract boolean isDisplayLocal();
298+
299+ /*
300+ * ----DISPLAY CHANGE SUPPORT----
301+ */
302+
303+ protected SunDisplayChanger displayChanger = new SunDisplayChanger();
304+
305+ /**
306+ * Add a DisplayChangeListener to be notified when the display settings
307+ * are changed.
308+ */
309+ public void addDisplayChangedListener(DisplayChangedListener client) {
310+ displayChanger.add(client);
311+ }
312+
313+ /**
314+ * Remove a DisplayChangeListener from Win32GraphicsEnvironment
315+ */
316+ public void removeDisplayChangedListener(DisplayChangedListener client) {
317+ displayChanger.remove(client);
318+ }
319+
320+ /*
321+ * ----END DISPLAY CHANGE SUPPORT----
322+ */
323+
324+ /**
325+ * Returns true if FlipBufferStrategy with COPIED buffer contents
326+ * is preferred for this peer's GraphicsConfiguration over
327+ * BlitBufferStrategy, false otherwise.
328+ *
329+ * The reason FlipBS could be preferred is that in some configurations
330+ * an accelerated copy to the screen is supported (like Direct3D 9)
331+ *
332+ * @return true if flip strategy should be used, false otherwise
333+ */
334+ public boolean isFlipStrategyPreferred(ComponentPeer peer) {
335+ return false;
336+ }
337+}
java/pkg/sun/java2d/Surface.class+0−0

Binary file not shown.

java/pkg/sun/java2d/Surface.java+34−0
@@ -0,0 +1,34 @@
1+/*
2+ * Copyright (c) 2007, 2008, 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+
26+package sun.java2d;
27+
28+/**
29+ * This is a tag interface for a surface.
30+ * @see sun.java2d.SurfaceData
31+ * @see sun.java2d.pipe.hw.AccelSurface
32+ */
33+public interface Surface {
34+}
java/pkg/sun/java2d/SurfaceData$PixelToPgramLoopConverter.class+0−0

Binary file not shown.

java/pkg/sun/java2d/SurfaceData$PixelToShapeLoopConverter.class+0−0

Binary file not shown.

java/pkg/sun/java2d/SurfaceData.class+0−0

Binary file not shown.

java/pkg/sun/java2d/SurfaceData.java+1060−0
@@ -0,0 +1,1060 @@
1+/*
2+ * Copyright (c) 1999, 2010, 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+
26+package sun.java2d;
27+
28+import java.awt.Color;
29+import java.awt.Rectangle;
30+import java.awt.Transparency;
31+import java.awt.GraphicsConfiguration;
32+import java.awt.Image;
33+import java.awt.image.ColorModel;
34+import java.awt.image.IndexColorModel;
35+import java.awt.image.Raster;
36+
37+import sun.java2d.loops.RenderCache;
38+import sun.java2d.loops.RenderLoops;
39+import sun.java2d.loops.CompositeType;
40+import sun.java2d.loops.SurfaceType;
41+import sun.java2d.loops.MaskFill;
42+import sun.java2d.loops.DrawLine;
43+import sun.java2d.loops.FillRect;
44+import sun.java2d.loops.DrawRect;
45+import sun.java2d.loops.DrawPolygons;
46+import sun.java2d.loops.DrawPath;
47+import sun.java2d.loops.FillPath;
48+import sun.java2d.loops.FillSpans;
49+import sun.java2d.loops.FillParallelogram;
50+import sun.java2d.loops.DrawParallelogram;
51+import sun.java2d.loops.FontInfo;
52+import sun.java2d.loops.DrawGlyphList;
53+import sun.java2d.loops.DrawGlyphListAA;
54+import sun.java2d.loops.DrawGlyphListLCD;
55+import sun.java2d.pipe.LoopPipe;
56+import sun.java2d.pipe.ShapeDrawPipe;
57+import sun.java2d.pipe.ParallelogramPipe;
58+import sun.java2d.pipe.CompositePipe;
59+import sun.java2d.pipe.GeneralCompositePipe;
60+import sun.java2d.pipe.SpanClipRenderer;
61+import sun.java2d.pipe.SpanShapeRenderer;
62+import sun.java2d.pipe.AAShapePipe;
63+import sun.java2d.pipe.AlphaPaintPipe;
64+import sun.java2d.pipe.AlphaColorPipe;
65+import sun.java2d.pipe.PixelToShapeConverter;
66+import sun.java2d.pipe.PixelToParallelogramConverter;
67+import sun.java2d.pipe.TextPipe;
68+import sun.java2d.pipe.TextRenderer;
69+import sun.java2d.pipe.AATextRenderer;
70+import sun.java2d.pipe.LCDTextRenderer;
71+import sun.java2d.pipe.SolidTextRenderer;
72+import sun.java2d.pipe.OutlineTextRenderer;
73+import sun.java2d.pipe.DrawImagePipe;
74+import sun.java2d.pipe.DrawImage;
75+import sun.awt.SunHints;
76+import sun.awt.image.SurfaceManager;
77+import sun.java2d.pipe.LoopBasedPipe;
78+
79+/**
80+ * This class provides various pieces of information relevant to a
81+ * particular drawing surface. The information obtained from this
82+ * object describes the pixels of a particular instance of a drawing
83+ * surface and can only be shared among the various graphics objects
84+ * that target the same BufferedImage or the same screen Component.
85+ * <p>
86+ * Each SurfaceData object holds a StateTrackableDelegate object
87+ * which tracks both changes to the content of the pixels of this
88+ * surface and changes to the overall state of the pixels - such
89+ * as becoming invalid or losing the surface. The delegate is
90+ * marked "dirty" whenever the setSurfaceLost() or invalidate()
91+ * methods are called and should also be marked "dirty" by the
92+ * rendering pipelines whenever they modify the pixels of this
93+ * SurfaceData.
94+ * <p>
95+ * If you get a StateTracker from a SurfaceData and it reports
96+ * that it is still "current", then you can trust that the pixels
97+ * have not changed and that the SurfaceData is still valid and
98+ * has not lost its underlying storage (surfaceLost) since you
99+ * retrieved the tracker.
100+ */
101+public abstract class SurfaceData
102+ implements Transparency, DisposerTarget, StateTrackable, Surface
103+{
104+ private long pData;
105+ private boolean valid;
106+ private boolean surfaceLost; // = false;
107+ private SurfaceType surfaceType;
108+ private ColorModel colorModel;
109+
110+ private Object disposerReferent = new Object();
111+
112+ private static native void initIDs();
113+
114+ private Object blitProxyKey;
115+ private StateTrackableDelegate stateDelegate;
116+
117+ static {
118+ initIDs();
119+ }
120+
121+ protected SurfaceData(SurfaceType surfaceType, ColorModel cm) {
122+ this(State.STABLE, surfaceType, cm);
123+ }
124+
125+ protected SurfaceData(State state, SurfaceType surfaceType, ColorModel cm) {
126+ this(StateTrackableDelegate.createInstance(state), surfaceType, cm);
127+ }
128+
129+ protected SurfaceData(StateTrackableDelegate trackable,
130+ SurfaceType surfaceType, ColorModel cm)
131+ {
132+ this.stateDelegate = trackable;
133+ this.colorModel = cm;
134+ this.surfaceType = surfaceType;
135+ valid = true;
136+ }
137+
138+ protected SurfaceData(State state) {
139+ this.stateDelegate = StateTrackableDelegate.createInstance(state);
140+ valid = true;
141+ }
142+
143+ /**
144+ * Subclasses can set a "blit proxy key" which will be used
145+ * along with the SurfaceManager.getCacheData() mechanism to
146+ * store acceleration-compatible cached copies of source images.
147+ * This key is a "tag" used to identify which cached copies
148+ * are compatible with this destination SurfaceData.
149+ * The getSourceSurfaceData() method uses this key to manage
150+ * cached copies of a source image as described below.
151+ * <p>
152+ * The Object used as this key should be as unique as it needs
153+ * to be to ensure that multiple acceleratible destinations can
154+ * each store their cached copies separately under different keys
155+ * without interfering with each other or getting back the wrong
156+ * cached copy.
157+ * <p>
158+ * Many acceleratable SurfaceData objects can use their own
159+ * GraphicsConfiguration as their proxy key as the GC object will
160+ * typically be unique to a given screen and pixel format, but
161+ * other rendering destinations may have more or less stringent
162+ * sharing requirements. For instance, X11 pixmaps can be
163+ * shared on a given screen by any GraphicsConfiguration that
164+ * has the same depth and SurfaceType. Multiple such GCs with
165+ * the same depth and SurfaceType can exist per screen so storing
166+ * a different cached proxy for each would be a waste. One can
167+ * imagine platforms where a single cached copy can be created
168+ * and shared across all screens and pixel formats - such
169+ * implementations could use a single heavily shared key Object.
170+ */
171+ protected void setBlitProxyKey(Object key) {
172+ // Caching is effectively disabled if we never have a proxy key
173+ // since the getSourceSurfaceData() method only does caching
174+ // if the key is not null.
175+ if (SurfaceDataProxy.isCachingAllowed()) {
176+ this.blitProxyKey = key;
177+ }
178+ }
179+
180+ /**
181+ * This method is called on a destination SurfaceData to choose
182+ * the best SurfaceData from a source Image for an imaging
183+ * operation, with help from its SurfaceManager.
184+ * The method may determine that the default SurfaceData was
185+ * really the best choice in the first place, or it may decide
186+ * to use a cached surface. Some general decisions about whether
187+ * acceleration is enabled are made by this method, but any
188+ * decision based on the type of the source image is made in
189+ * the makeProxyFor method below when it comes up with the
190+ * appropriate SurfaceDataProxy instance.
191+ * The parameters describe the type of imaging operation being performed.
192+ * <p>
193+ * If a blitProxyKey was supplied by the subclass then it is
194+ * used to potentially override the choice of source SurfaceData.
195+ * The outline of this process is:
196+ * <ol>
197+ * <li> Image pipeline asks destSD to find an appropriate
198+ * srcSD for a given source Image object.
199+ * <li> destSD gets the SurfaceManager of the source Image
200+ * and first retrieves the default SD from it using
201+ * getPrimarySurfaceData()
202+ * <li> destSD uses its "blit proxy key" (if set) to look for
203+ * some cached data stored in the source SurfaceManager
204+ * <li> If the cached data is null then makeProxyFor() is used
205+ * to create some cached data which is stored back in the
206+ * source SurfaceManager under the same key for future uses.
207+ * <li> The cached data will be a SurfaceDataProxy object.
208+ * <li> The SurfaceDataProxy object is then consulted to
209+ * return a replacement SurfaceData object (typically
210+ * a cached copy if appropriate, or the original if not).
211+ * </ol>
212+ */
213+ public SurfaceData getSourceSurfaceData(Image img,
214+ int txtype,
215+ CompositeType comp,
216+ Color bgColor)
217+ {
218+ SurfaceManager srcMgr = SurfaceManager.getManager(img);
219+ SurfaceData srcData = srcMgr.getPrimarySurfaceData();
220+ if (img.getAccelerationPriority() > 0.0f &&
221+ blitProxyKey != null)
222+ {
223+ SurfaceDataProxy sdp =
224+ (SurfaceDataProxy) srcMgr.getCacheData(blitProxyKey);
225+ if (sdp == null || !sdp.isValid()) {
226+ if (srcData.getState() == State.UNTRACKABLE) {
227+ sdp = SurfaceDataProxy.UNCACHED;
228+ } else {
229+ sdp = makeProxyFor(srcData);
230+ }
231+ srcMgr.setCacheData(blitProxyKey, sdp);
232+ }
233+ srcData = sdp.replaceData(srcData, txtype, comp, bgColor);
234+ }
235+ return srcData;
236+ }
237+
238+ /**
239+ * This method is called on a destination SurfaceData to choose
240+ * a proper SurfaceDataProxy subclass for a source SurfaceData
241+ * to use to control when and with what surface to override a
242+ * given image operation. The argument is the default SurfaceData
243+ * for the source Image.
244+ * <p>
245+ * The type of the return object is chosen based on the
246+ * acceleration capabilities of this SurfaceData and the
247+ * type of the given source SurfaceData object.
248+ * <p>
249+ * In some cases the original SurfaceData will always be the
250+ * best choice to use to blit to this SurfaceData. This can
251+ * happen if the source image is a hardware surface of the
252+ * same type as this one and so acceleration will happen without
253+ * any caching. It may also be the case that the source image
254+ * can never be accelerated on this SurfaceData - for example
255+ * because it is translucent and there are no accelerated
256+ * translucent image ops for this surface.
257+ * <p>
258+ * In those cases there is a special SurfaceDataProxy.UNCACHED
259+ * instance that represents a NOP for caching purposes - it
260+ * always returns the original sourceSD object as the replacement
261+ * copy so no caching is ever performed.
262+ */
263+ public SurfaceDataProxy makeProxyFor(SurfaceData srcData) {
264+ return SurfaceDataProxy.UNCACHED;
265+ }
266+
267+ /**
268+ * Extracts the SurfaceManager from the given Image, and then
269+ * returns the SurfaceData object that would best be suited as the
270+ * destination surface in some rendering operation.
271+ */
272+ public static SurfaceData getPrimarySurfaceData(Image img) {
273+ SurfaceManager sMgr = SurfaceManager.getManager(img);
274+ return sMgr.getPrimarySurfaceData();
275+ }
276+
277+ /**
278+ * Restores the contents of the given Image and then returns the new
279+ * SurfaceData object in use by the Image's SurfaceManager.
280+ */
281+ public static SurfaceData restoreContents(Image img) {
282+ SurfaceManager sMgr = SurfaceManager.getManager(img);
283+ return sMgr.restoreContents();
284+ }
285+
286+ public State getState() {
287+ return stateDelegate.getState();
288+ }
289+
290+ public StateTracker getStateTracker() {
291+ return stateDelegate.getStateTracker();
292+ }
293+
294+ /**
295+ * Marks this surface as dirty.
296+ */
297+ public final void markDirty() {
298+ stateDelegate.markDirty();
299+ }
300+
301+ /**
302+ * Sets the value of the surfaceLost variable, which indicates whether
303+ * something has happened to the rendering surface such that it needs
304+ * to be restored and re-rendered.
305+ */
306+ public void setSurfaceLost(boolean lost) {
307+ surfaceLost = lost;
308+ stateDelegate.markDirty();
309+ }
310+
311+ public boolean isSurfaceLost() {
312+ return surfaceLost;
313+ }
314+
315+ /**
316+ * Returns a boolean indicating whether or not this SurfaceData is valid.
317+ */
318+ public final boolean isValid() {
319+ return valid;
320+ }
321+
322+ public Object getDisposerReferent() {
323+ return disposerReferent;
324+ }
325+
326+ public long getNativeOps() {
327+ return pData;
328+ }
329+
330+ /**
331+ * Sets this SurfaceData object to the invalid state. All Graphics
332+ * objects must get a new SurfaceData object via the refresh method
333+ * and revalidate their pipelines before continuing.
334+ */
335+ public void invalidate() {
336+ valid = false;
337+ stateDelegate.markDirty();
338+ }
339+
340+ /**
341+ * Certain changes in the configuration of a surface require the
342+ * invalidation of existing associated SurfaceData objects and
343+ * the creation of brand new ones. These changes include size,
344+ * ColorModel, or SurfaceType. Existing Graphics objects
345+ * which are directed at such surfaces, however, must continue
346+ * to render to them even after the change occurs underneath
347+ * the covers. The getReplacement() method is called from
348+ * SunGraphics2D.revalidateAll() when the associated SurfaceData
349+ * is found to be invalid so that a Graphics object can continue
350+ * to render to the surface in its new configuration.
351+ *
352+ * Such changes only tend to happen to window based surfaces since
353+ * most image based surfaces never change size or pixel format.
354+ * Even VolatileImage objects never change size and they only
355+ * change their pixel format when manually validated against a
356+ * new GraphicsConfiguration, at which point old Graphics objects
357+ * are no longer expected to render to them after the validation
358+ * step. Thus, only window based surfaces really need to deal
359+ * with this form of replacement.
360+ */
361+ public abstract SurfaceData getReplacement();
362+
363+ protected static final LoopPipe colorPrimitives;
364+
365+ public static final TextPipe outlineTextRenderer;
366+ public static final TextPipe solidTextRenderer;
367+ public static final TextPipe aaTextRenderer;
368+ public static final TextPipe lcdTextRenderer;
369+
370+ protected static final AlphaColorPipe colorPipe;
371+ protected static final PixelToShapeConverter colorViaShape;
372+ protected static final PixelToParallelogramConverter colorViaPgram;
373+ protected static final TextPipe colorText;
374+ protected static final CompositePipe clipColorPipe;
375+ protected static final TextPipe clipColorText;
376+ protected static final AAShapePipe AAColorShape;
377+ protected static final PixelToParallelogramConverter AAColorViaShape;
378+ protected static final PixelToParallelogramConverter AAColorViaPgram;
379+ protected static final AAShapePipe AAClipColorShape;
380+ protected static final PixelToParallelogramConverter AAClipColorViaShape;
381+
382+ protected static final CompositePipe paintPipe;
383+ protected static final SpanShapeRenderer paintShape;
384+ protected static final PixelToShapeConverter paintViaShape;
385+ protected static final TextPipe paintText;
386+ protected static final CompositePipe clipPaintPipe;
387+ protected static final TextPipe clipPaintText;
388+ protected static final AAShapePipe AAPaintShape;
389+ protected static final PixelToParallelogramConverter AAPaintViaShape;
390+ protected static final AAShapePipe AAClipPaintShape;
391+ protected static final PixelToParallelogramConverter AAClipPaintViaShape;
392+
393+ protected static final CompositePipe compPipe;
394+ protected static final SpanShapeRenderer compShape;
395+ protected static final PixelToShapeConverter compViaShape;
396+ protected static final TextPipe compText;
397+ protected static final CompositePipe clipCompPipe;
398+ protected static final TextPipe clipCompText;
399+ protected static final AAShapePipe AACompShape;
400+ protected static final PixelToParallelogramConverter AACompViaShape;
401+ protected static final AAShapePipe AAClipCompShape;
402+ protected static final PixelToParallelogramConverter AAClipCompViaShape;
403+
404+ protected static final DrawImagePipe imagepipe;
405+
406+ // Utility subclass to add the LoopBasedPipe tagging interface
407+ static class PixelToShapeLoopConverter
408+ extends PixelToShapeConverter
409+ implements LoopBasedPipe
410+ {
411+ public PixelToShapeLoopConverter(ShapeDrawPipe pipe) {
412+ super(pipe);
413+ }
414+ }
415+
416+ // Utility subclass to add the LoopBasedPipe tagging interface
417+ static class PixelToPgramLoopConverter
418+ extends PixelToParallelogramConverter
419+ implements LoopBasedPipe
420+ {
421+ public PixelToPgramLoopConverter(ShapeDrawPipe shapepipe,
422+ ParallelogramPipe pgrampipe,
423+ double minPenSize,
424+ double normPosition,
425+ boolean adjustfill)
426+ {
427+ super(shapepipe, pgrampipe, minPenSize, normPosition, adjustfill);
428+ }
429+ }
430+
431+ private static PixelToParallelogramConverter
432+ makeConverter(AAShapePipe renderer,
433+ ParallelogramPipe pgrampipe)
434+ {
435+ return new PixelToParallelogramConverter(renderer,
436+ pgrampipe,
437+ 1.0/8.0, 0.499,
438+ false);
439+ }
440+
441+ private static PixelToParallelogramConverter
442+ makeConverter(AAShapePipe renderer)
443+ {
444+ return makeConverter(renderer, renderer);
445+ }
446+
447+ static {
448+ colorPrimitives = new LoopPipe();
449+
450+ outlineTextRenderer = new OutlineTextRenderer();
451+ solidTextRenderer = new SolidTextRenderer();
452+ aaTextRenderer = new AATextRenderer();
453+ lcdTextRenderer = new LCDTextRenderer();
454+
455+ colorPipe = new AlphaColorPipe();
456+ // colorShape = colorPrimitives;
457+ colorViaShape = new PixelToShapeLoopConverter(colorPrimitives);
458+ colorViaPgram = new PixelToPgramLoopConverter(colorPrimitives,
459+ colorPrimitives,
460+ 1.0, 0.25, true);
461+ colorText = new TextRenderer(colorPipe);
462+ clipColorPipe = new SpanClipRenderer(colorPipe);
463+ clipColorText = new TextRenderer(clipColorPipe);
464+ AAColorShape = new AAShapePipe(colorPipe);
465+ AAColorViaShape = makeConverter(AAColorShape);
466+ AAColorViaPgram = makeConverter(AAColorShape, colorPipe);
467+ AAClipColorShape = new AAShapePipe(clipColorPipe);
468+ AAClipColorViaShape = makeConverter(AAClipColorShape);
469+
470+ paintPipe = new AlphaPaintPipe();
471+ paintShape = new SpanShapeRenderer.Composite(paintPipe);
472+ paintViaShape = new PixelToShapeConverter(paintShape);
473+ paintText = new TextRenderer(paintPipe);
474+ clipPaintPipe = new SpanClipRenderer(paintPipe);
475+ clipPaintText = new TextRenderer(clipPaintPipe);
476+ AAPaintShape = new AAShapePipe(paintPipe);
477+ AAPaintViaShape = makeConverter(AAPaintShape);
478+ AAClipPaintShape = new AAShapePipe(clipPaintPipe);
479+ AAClipPaintViaShape = makeConverter(AAClipPaintShape);
480+
481+ compPipe = new GeneralCompositePipe();
482+ compShape = new SpanShapeRenderer.Composite(compPipe);
483+ compViaShape = new PixelToShapeConverter(compShape);
484+ compText = new TextRenderer(compPipe);
485+ clipCompPipe = new SpanClipRenderer(compPipe);
486+ clipCompText = new TextRenderer(clipCompPipe);
487+ AACompShape = new AAShapePipe(compPipe);
488+ AACompViaShape = makeConverter(AACompShape);
489+ AAClipCompShape = new AAShapePipe(clipCompPipe);
490+ AAClipCompViaShape = makeConverter(AAClipCompShape);
491+
492+ imagepipe = new DrawImage();
493+ }
494+
495+ /* Not all surfaces and rendering mode combinations support LCD text. */
496+ static final int LOOP_UNKNOWN = 0;
497+ static final int LOOP_FOUND = 1;
498+ static final int LOOP_NOTFOUND = 2;
499+ int haveLCDLoop;
500+ int havePgramXORLoop;
501+ int havePgramSolidLoop;
502+
503+ public boolean canRenderLCDText(SunGraphics2D sg2d) {
504+ // For now the answer can only be true in the following cases:
505+ if (sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY &&
506+ sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR &&
507+ sg2d.clipState <= SunGraphics2D.CLIP_RECTANGULAR &&
508+ sg2d.surfaceData.getTransparency() == Transparency.OPAQUE)
509+ {
510+ if (haveLCDLoop == LOOP_UNKNOWN) {
511+ DrawGlyphListLCD loop =
512+ DrawGlyphListLCD.locate(SurfaceType.AnyColor,
513+ CompositeType.SrcNoEa,
514+ getSurfaceType());
515+ haveLCDLoop = (loop != null) ? LOOP_FOUND : LOOP_NOTFOUND;
516+ }
517+ return haveLCDLoop == LOOP_FOUND;
518+ }
519+ return false; /* for now - in the future we may want to search */
520+ }
521+
522+ public boolean canRenderParallelograms(SunGraphics2D sg2d) {
523+ if (sg2d.paintState <= sg2d.PAINT_ALPHACOLOR) {
524+ if (sg2d.compositeState == sg2d.COMP_XOR) {
525+ if (havePgramXORLoop == LOOP_UNKNOWN) {
526+ FillParallelogram loop =
527+ FillParallelogram.locate(SurfaceType.AnyColor,
528+ CompositeType.Xor,
529+ getSurfaceType());
530+ havePgramXORLoop =
531+ (loop != null) ? LOOP_FOUND : LOOP_NOTFOUND;
532+ }
533+ return havePgramXORLoop == LOOP_FOUND;
534+ } else if (sg2d.compositeState <= sg2d.COMP_ISCOPY &&
535+ sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON &&
536+ sg2d.clipState != sg2d.CLIP_SHAPE)
537+ {
538+ if (havePgramSolidLoop == LOOP_UNKNOWN) {
539+ FillParallelogram loop =
540+ FillParallelogram.locate(SurfaceType.AnyColor,
541+ CompositeType.SrcNoEa,
542+ getSurfaceType());
543+ havePgramSolidLoop =
544+ (loop != null) ? LOOP_FOUND : LOOP_NOTFOUND;
545+ }
546+ return havePgramSolidLoop == LOOP_FOUND;
547+ }
548+ }
549+ return false;
550+ }
551+
552+ public void validatePipe(SunGraphics2D sg2d) {
553+ sg2d.imagepipe = imagepipe;
554+ if (sg2d.compositeState == sg2d.COMP_XOR) {
555+ if (sg2d.paintState > sg2d.PAINT_ALPHACOLOR) {
556+ sg2d.drawpipe = paintViaShape;
557+ sg2d.fillpipe = paintViaShape;
558+ sg2d.shapepipe = paintShape;
559+ // REMIND: Ideally custom paint mode would use glyph
560+ // rendering as opposed to outline rendering but the
561+ // glyph paint rendering pipeline uses MaskBlit which
562+ // is not defined for XOR. This means that text drawn
563+ // in XOR mode with a Color object is different than
564+ // text drawn in XOR mode with a Paint object.
565+ sg2d.textpipe = outlineTextRenderer;
566+ } else {
567+ PixelToShapeConverter converter;
568+ if (canRenderParallelograms(sg2d)) {
569+ converter = colorViaPgram;
570+ // Note that we use the transforming pipe here because it
571+ // will examine the shape and possibly perform an optimized
572+ // operation if it can be simplified. The simplifications
573+ // will be valid for all STROKE and TRANSFORM types.
574+ sg2d.shapepipe = colorViaPgram;
575+ } else {
576+ converter = colorViaShape;
577+ sg2d.shapepipe = colorPrimitives;
578+ }
579+ if (sg2d.clipState == sg2d.CLIP_SHAPE) {
580+ sg2d.drawpipe = converter;
581+ sg2d.fillpipe = converter;
582+ // REMIND: We should not be changing text strategies
583+ // between outline and glyph rendering based upon the
584+ // presence of a complex clip as that could cause a
585+ // mismatch when drawing the same text both clipped
586+ // and unclipped on two separate rendering passes.
587+ // Unfortunately, all of the clipped glyph rendering
588+ // pipelines rely on the use of the MaskBlit operation
589+ // which is not defined for XOR.
590+ sg2d.textpipe = outlineTextRenderer;
591+ } else {
592+ if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE) {
593+ sg2d.drawpipe = converter;
594+ sg2d.fillpipe = converter;
595+ } else {
596+ if (sg2d.strokeState != sg2d.STROKE_THIN) {
597+ sg2d.drawpipe = converter;
598+ } else {
599+ sg2d.drawpipe = colorPrimitives;
600+ }
601+ sg2d.fillpipe = colorPrimitives;
602+ }
603+ sg2d.textpipe = solidTextRenderer;
604+ }
605+ // assert(sg2d.surfaceData == this);
606+ }
607+ } else if (sg2d.compositeState == sg2d.COMP_CUSTOM) {
608+ if (sg2d.antialiasHint == SunHints.INTVAL_ANTIALIAS_ON) {
609+ if (sg2d.clipState == sg2d.CLIP_SHAPE) {
610+ sg2d.drawpipe = AAClipCompViaShape;
611+ sg2d.fillpipe = AAClipCompViaShape;
612+ sg2d.shapepipe = AAClipCompViaShape;
613+ sg2d.textpipe = clipCompText;
614+ } else {
615+ sg2d.drawpipe = AACompViaShape;
616+ sg2d.fillpipe = AACompViaShape;
617+ sg2d.shapepipe = AACompViaShape;
618+ sg2d.textpipe = compText;
619+ }
620+ } else {
621+ sg2d.drawpipe = compViaShape;
622+ sg2d.fillpipe = compViaShape;
623+ sg2d.shapepipe = compShape;
624+ if (sg2d.clipState == sg2d.CLIP_SHAPE) {
625+ sg2d.textpipe = clipCompText;
626+ } else {
627+ sg2d.textpipe = compText;
628+ }
629+ }
630+ } else if (sg2d.antialiasHint == SunHints.INTVAL_ANTIALIAS_ON) {
631+ sg2d.alphafill = getMaskFill(sg2d);
632+ // assert(sg2d.surfaceData == this);
633+ if (sg2d.alphafill != null) {
634+ if (sg2d.clipState == sg2d.CLIP_SHAPE) {
635+ sg2d.drawpipe = AAClipColorViaShape;
636+ sg2d.fillpipe = AAClipColorViaShape;
637+ sg2d.shapepipe = AAClipColorViaShape;
638+ sg2d.textpipe = clipColorText;
639+ } else {
640+ PixelToParallelogramConverter converter =
641+ (sg2d.alphafill.canDoParallelograms()
642+ ? AAColorViaPgram
643+ : AAColorViaShape);
644+ sg2d.drawpipe = converter;
645+ sg2d.fillpipe = converter;
646+ sg2d.shapepipe = converter;
647+ if (sg2d.paintState > sg2d.PAINT_ALPHACOLOR ||
648+ sg2d.compositeState > sg2d.COMP_ISCOPY)
649+ {
650+ sg2d.textpipe = colorText;
651+ } else {
652+ sg2d.textpipe = getTextPipe(sg2d, true /* AA==ON */);
653+ }
654+ }
655+ } else {
656+ if (sg2d.clipState == sg2d.CLIP_SHAPE) {
657+ sg2d.drawpipe = AAClipPaintViaShape;
658+ sg2d.fillpipe = AAClipPaintViaShape;
659+ sg2d.shapepipe = AAClipPaintViaShape;
660+ sg2d.textpipe = clipPaintText;
661+ } else {
662+ sg2d.drawpipe = AAPaintViaShape;
663+ sg2d.fillpipe = AAPaintViaShape;
664+ sg2d.shapepipe = AAPaintViaShape;
665+ sg2d.textpipe = paintText;
666+ }
667+ }
668+ } else if (sg2d.paintState > sg2d.PAINT_ALPHACOLOR ||
669+ sg2d.compositeState > sg2d.COMP_ISCOPY ||
670+ sg2d.clipState == sg2d.CLIP_SHAPE)
671+ {
672+ sg2d.drawpipe = paintViaShape;
673+ sg2d.fillpipe = paintViaShape;
674+ sg2d.shapepipe = paintShape;
675+ sg2d.alphafill = getMaskFill(sg2d);
676+ // assert(sg2d.surfaceData == this);
677+ if (sg2d.alphafill != null) {
678+ if (sg2d.clipState == sg2d.CLIP_SHAPE) {
679+ sg2d.textpipe = clipColorText;
680+ } else {
681+ sg2d.textpipe = colorText;
682+ }
683+ } else {
684+ if (sg2d.clipState == sg2d.CLIP_SHAPE) {
685+ sg2d.textpipe = clipPaintText;
686+ } else {
687+ sg2d.textpipe = paintText;
688+ }
689+ }
690+ } else {
691+ PixelToShapeConverter converter;
692+ if (canRenderParallelograms(sg2d)) {
693+ converter = colorViaPgram;
694+ // Note that we use the transforming pipe here because it
695+ // will examine the shape and possibly perform an optimized
696+ // operation if it can be simplified. The simplifications
697+ // will be valid for all STROKE and TRANSFORM types.
698+ sg2d.shapepipe = colorViaPgram;
699+ } else {
700+ converter = colorViaShape;
701+ sg2d.shapepipe = colorPrimitives;
702+ }
703+ if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE) {
704+ sg2d.drawpipe = converter;
705+ sg2d.fillpipe = converter;
706+ } else {
707+ if (sg2d.strokeState != sg2d.STROKE_THIN) {
708+ sg2d.drawpipe = converter;
709+ } else {
710+ sg2d.drawpipe = colorPrimitives;
711+ }
712+ sg2d.fillpipe = colorPrimitives;
713+ }
714+
715+ sg2d.textpipe = getTextPipe(sg2d, false /* AA==OFF */);
716+ // assert(sg2d.surfaceData == this);
717+ }
718+
719+ // check for loops
720+ if (sg2d.textpipe instanceof LoopBasedPipe ||
721+ sg2d.shapepipe instanceof LoopBasedPipe ||
722+ sg2d.fillpipe instanceof LoopBasedPipe ||
723+ sg2d.drawpipe instanceof LoopBasedPipe ||
724+ sg2d.imagepipe instanceof LoopBasedPipe)
725+ {
726+ sg2d.loops = getRenderLoops(sg2d);
727+ }
728+ }
729+
730+ /* Return the text pipe to be used based on the graphics AA hint setting,
731+ * and the rest of the graphics state is compatible with these loops.
732+ * If the text AA hint is "DEFAULT", then the AA graphics hint requests
733+ * the AA text renderer, else it requests the B&W text renderer.
734+ */
735+ private TextPipe getTextPipe(SunGraphics2D sg2d, boolean aaHintIsOn) {
736+
737+ /* Try to avoid calling getFontInfo() unless its needed to
738+ * resolve one of the new AA types.
739+ */
740+ switch (sg2d.textAntialiasHint) {
741+ case SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT:
742+ if (aaHintIsOn) {
743+ return aaTextRenderer;
744+ } else {
745+ return solidTextRenderer;
746+ }
747+ case SunHints.INTVAL_TEXT_ANTIALIAS_OFF:
748+ return solidTextRenderer;
749+
750+ case SunHints.INTVAL_TEXT_ANTIALIAS_ON:
751+ return aaTextRenderer;
752+
753+ default:
754+ switch (sg2d.getFontInfo().aaHint) {
755+
756+ case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_HRGB:
757+ case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_VRGB:
758+ return lcdTextRenderer;
759+
760+ case SunHints.INTVAL_TEXT_ANTIALIAS_ON:
761+ return aaTextRenderer;
762+
763+ case SunHints.INTVAL_TEXT_ANTIALIAS_OFF:
764+ return solidTextRenderer;
765+
766+ /* This should not be reached as the FontInfo will
767+ * always explicitly set its hint value. So whilst
768+ * this could be collapsed to returning say just
769+ * solidTextRenderer, or even removed, its left
770+ * here in case DEFAULT is ever passed in.
771+ */
772+ default:
773+ if (aaHintIsOn) {
774+ return aaTextRenderer;
775+ } else {
776+ return solidTextRenderer;
777+ }
778+ }
779+ }
780+ }
781+
782+ private static SurfaceType getPaintSurfaceType(SunGraphics2D sg2d) {
783+ switch (sg2d.paintState) {
784+ case SunGraphics2D.PAINT_OPAQUECOLOR:
785+ return SurfaceType.OpaqueColor;
786+ case SunGraphics2D.PAINT_ALPHACOLOR:
787+ return SurfaceType.AnyColor;
788+ case SunGraphics2D.PAINT_GRADIENT:
789+ if (sg2d.paint.getTransparency() == OPAQUE) {
790+ return SurfaceType.OpaqueGradientPaint;
791+ } else {
792+ return SurfaceType.GradientPaint;
793+ }
794+ case SunGraphics2D.PAINT_LIN_GRADIENT:
795+ if (sg2d.paint.getTransparency() == OPAQUE) {
796+ return SurfaceType.OpaqueLinearGradientPaint;
797+ } else {
798+ return SurfaceType.LinearGradientPaint;
799+ }
800+ case SunGraphics2D.PAINT_RAD_GRADIENT:
801+ if (sg2d.paint.getTransparency() == OPAQUE) {
802+ return SurfaceType.OpaqueRadialGradientPaint;
803+ } else {
804+ return SurfaceType.RadialGradientPaint;
805+ }
806+ case SunGraphics2D.PAINT_TEXTURE:
807+ if (sg2d.paint.getTransparency() == OPAQUE) {
808+ return SurfaceType.OpaqueTexturePaint;
809+ } else {
810+ return SurfaceType.TexturePaint;
811+ }
812+ default:
813+ case SunGraphics2D.PAINT_CUSTOM:
814+ return SurfaceType.AnyPaint;
815+ }
816+ }
817+
818+ private static CompositeType getFillCompositeType(SunGraphics2D sg2d) {
819+ CompositeType compType = sg2d.imageComp;
820+ if (sg2d.compositeState == sg2d.COMP_ISCOPY) {
821+ if (compType == CompositeType.SrcOverNoEa) {
822+ compType = CompositeType.OpaqueSrcOverNoEa;
823+ } else {
824+ compType = CompositeType.SrcNoEa;
825+ }
826+ }
827+ return compType;
828+ }
829+
830+ /**
831+ * Returns a MaskFill object that can be used on this destination
832+ * with the source (paint) and composite types determined by the given
833+ * SunGraphics2D, or null if no such MaskFill object can be located.
834+ * Subclasses can override this method if they wish to filter other
835+ * attributes (such as the hardware capabilities of the destination
836+ * surface) before returning a specific MaskFill object.
837+ */
838+ protected MaskFill getMaskFill(SunGraphics2D sg2d) {
839+ SurfaceType src = getPaintSurfaceType(sg2d);
840+ CompositeType comp = getFillCompositeType(sg2d);
841+ SurfaceType dst = getSurfaceType();
842+ return MaskFill.getFromCache(src, comp, dst);
843+ }
844+
845+ private static RenderCache loopcache = new RenderCache(30);
846+
847+ /**
848+ * Return a RenderLoops object containing all of the basic
849+ * GraphicsPrimitive objects for rendering to the destination
850+ * surface with the current attributes of the given SunGraphics2D.
851+ */
852+ public RenderLoops getRenderLoops(SunGraphics2D sg2d) {
853+ SurfaceType src = getPaintSurfaceType(sg2d);
854+ CompositeType comp = getFillCompositeType(sg2d);
855+ SurfaceType dst = sg2d.getSurfaceData().getSurfaceType();
856+
857+ Object o = loopcache.get(src, comp, dst);
858+ if (o != null) {
859+ return (RenderLoops) o;
860+ }
861+
862+ RenderLoops loops = makeRenderLoops(src, comp, dst);
863+ loopcache.put(src, comp, dst, loops);
864+ return loops;
865+ }
866+
867+ /**
868+ * Construct and return a RenderLoops object containing all of
869+ * the basic GraphicsPrimitive objects for rendering to the
870+ * destination surface with the given source, destination, and
871+ * composite types.
872+ */
873+ public static RenderLoops makeRenderLoops(SurfaceType src,
874+ CompositeType comp,
875+ SurfaceType dst)
876+ {
877+ RenderLoops loops = new RenderLoops();
878+ loops.drawLineLoop = DrawLine.locate(src, comp, dst);
879+ loops.fillRectLoop = FillRect.locate(src, comp, dst);
880+ loops.drawRectLoop = DrawRect.locate(src, comp, dst);
881+ loops.drawPolygonsLoop = DrawPolygons.locate(src, comp, dst);
882+ loops.drawPathLoop = DrawPath.locate(src, comp, dst);
883+ loops.fillPathLoop = FillPath.locate(src, comp, dst);
884+ loops.fillSpansLoop = FillSpans.locate(src, comp, dst);
885+ loops.fillParallelogramLoop = FillParallelogram.locate(src, comp, dst);
886+ loops.drawParallelogramLoop = DrawParallelogram.locate(src, comp, dst);
887+ loops.drawGlyphListLoop = DrawGlyphList.locate(src, comp, dst);
888+ loops.drawGlyphListAALoop = DrawGlyphListAA.locate(src, comp, dst);
889+ loops.drawGlyphListLCDLoop = DrawGlyphListLCD.locate(src, comp, dst);
890+ /*
891+ System.out.println("drawLine: "+loops.drawLineLoop);
892+ System.out.println("fillRect: "+loops.fillRectLoop);
893+ System.out.println("drawRect: "+loops.drawRectLoop);
894+ System.out.println("drawPolygons: "+loops.drawPolygonsLoop);
895+ System.out.println("fillSpans: "+loops.fillSpansLoop);
896+ System.out.println("drawGlyphList: "+loops.drawGlyphListLoop);
897+ System.out.println("drawGlyphListAA: "+loops.drawGlyphListAALoop);
898+ System.out.println("drawGlyphListLCD: "+loops.drawGlyphListLCDLoop);
899+ */
900+ return loops;
901+ }
902+
903+ /**
904+ * Return the GraphicsConfiguration object that describes this
905+ * destination surface.
906+ */
907+ public abstract GraphicsConfiguration getDeviceConfiguration();
908+
909+ /**
910+ * Return the SurfaceType object that describes the destination
911+ * surface.
912+ */
913+ public final SurfaceType getSurfaceType() {
914+ return surfaceType;
915+ }
916+
917+ /**
918+ * Return the ColorModel for the destination surface.
919+ */
920+ public final ColorModel getColorModel() {
921+ return colorModel;
922+ }
923+
924+ /**
925+ * Returns the type of this <code>Transparency</code>.
926+ * @return the field type of this <code>Transparency</code>, which is
927+ * either OPAQUE, BITMASK or TRANSLUCENT.
928+ */
929+ public int getTransparency() {
930+ return getColorModel().getTransparency();
931+ }
932+
933+ /**
934+ * Return a readable Raster which contains the pixels for the
935+ * specified rectangular region of the destination surface.
936+ * The coordinate origin of the returned Raster is the same as
937+ * the device space origin of the destination surface.
938+ * In some cases the returned Raster might also be writeable.
939+ * In most cases, the returned Raster might contain more pixels
940+ * than requested.
941+ *
942+ * @see useTightBBoxes
943+ */
944+ public abstract Raster getRaster(int x, int y, int w, int h);
945+
946+ /**
947+ * Does the pixel accessibility of the destination surface
948+ * suggest that rendering algorithms might want to take
949+ * extra time to calculate a more accurate bounding box for
950+ * the operation being performed?
951+ * The typical case when this will be true is when a copy of
952+ * the pixels has to be made when doing a getRaster. The
953+ * fewer pixels copied, the faster the operation will go.
954+ *
955+ * @see getRaster
956+ */
957+ public boolean useTightBBoxes() {
958+ // Note: The native equivalent would trigger on VISIBLE_TO_NATIVE
959+ // REMIND: This is not used - should be obsoleted maybe
960+ return true;
961+ }
962+
963+ /**
964+ * Returns the pixel data for the specified Argb value packed
965+ * into an integer for easy storage and conveyance.
966+ */
967+ public int pixelFor(int rgb) {
968+ return surfaceType.pixelFor(rgb, colorModel);
969+ }
970+
971+ /**
972+ * Returns the pixel data for the specified color packed into an
973+ * integer for easy storage and conveyance.
974+ *
975+ * This method will use the getRGB() method of the Color object
976+ * and defer to the pixelFor(int rgb) method if not overridden.
977+ *
978+ * For now this is a convenience function, but for cases where
979+ * the highest quality color conversion is requested, this method
980+ * should be overridden in those cases so that a more direct
981+ * conversion of the color to the destination color space
982+ * can be done using the additional information in the Color
983+ * object.
984+ */
985+ public int pixelFor(Color c) {
986+ return pixelFor(c.getRGB());
987+ }
988+
989+ /**
990+ * Returns the Argb representation for the specified integer value
991+ * which is packed in the format of the associated ColorModel.
992+ */
993+ public int rgbFor(int pixel) {
994+ return surfaceType.rgbFor(pixel, colorModel);
995+ }
996+
997+ /**
998+ * Returns the bounds of the destination surface.
999+ */
1000+ public abstract Rectangle getBounds();
1001+
1002+ static java.security.Permission compPermission;
1003+
1004+ /**
1005+ * Performs Security Permissions checks to see if a Custom
1006+ * Composite object should be allowed access to the pixels
1007+ * of this surface.
1008+ */
1009+ protected void checkCustomComposite() {
1010+ SecurityManager sm = System.getSecurityManager();
1011+ if (sm != null) {
1012+ if (compPermission == null) {
1013+ compPermission =
1014+ new java.awt.AWTPermission("readDisplayPixels");
1015+ }
1016+ sm.checkPermission(compPermission);
1017+ }
1018+ }
1019+
1020+ /**
1021+ * Fetches private field IndexColorModel.allgrayopaque
1022+ * which is true when all palette entries in the color
1023+ * model are gray and opaque.
1024+ */
1025+ protected static native boolean isOpaqueGray(IndexColorModel icm);
1026+
1027+ /**
1028+ * For our purposes null and NullSurfaceData are the same as
1029+ * they represent a disposed surface.
1030+ */
1031+ public static boolean isNull(SurfaceData sd) {
1032+ if (sd == null || sd == NullSurfaceData.theInstance) {
1033+ return true;
1034+ }
1035+ return false;
1036+ }
1037+
1038+ /**
1039+ * Performs a copyarea within this surface. Returns
1040+ * false if there is no algorithm to perform the copyarea
1041+ * given the current settings of the SunGraphics2D.
1042+ */
1043+ public boolean copyArea(SunGraphics2D sg2d,
1044+ int x, int y, int w, int h, int dx, int dy)
1045+ {
1046+ return false;
1047+ }
1048+
1049+ /**
1050+ * Synchronously releases resources associated with this surface.
1051+ */
1052+ public void flush() {}
1053+
1054+ /**
1055+ * Returns destination associated with this SurfaceData. This could be
1056+ * either an Image or a Component; subclasses of SurfaceData are
1057+ * responsible for returning the appropriate object.
1058+ */
1059+ public abstract Object getDestination();
1060+}
java/pkg/sun/java2d/SurfaceDataProxy$1.class+0−0

Binary file not shown.

java/pkg/sun/java2d/SurfaceDataProxy$CountdownTracker.class+0−0

Binary file not shown.

java/pkg/sun/java2d/SurfaceDataProxy.class+0−0

Binary file not shown.

java/pkg/sun/java2d/SurfaceDataProxy.java+528−0
@@ -0,0 +1,528 @@
1+/*
2+ * Copyright (c) 2007, 2008, 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+
26+package sun.java2d;
27+
28+import java.awt.Color;
29+import java.awt.Rectangle;
30+import java.awt.AlphaComposite;
31+import java.awt.GraphicsEnvironment;
32+
33+import sun.awt.DisplayChangedListener;
34+import sun.java2d.StateTrackable.State;
35+import sun.java2d.loops.CompositeType;
36+import sun.java2d.loops.SurfaceType;
37+import sun.java2d.loops.Blit;
38+import sun.java2d.loops.BlitBg;
39+import sun.awt.image.SurfaceManager;
40+import sun.awt.image.SurfaceManager.FlushableCacheData;
41+
42+import java.security.AccessController;
43+import sun.security.action.GetPropertyAction;
44+
45+/**
46+ * The proxy class encapsulates the logic for managing alternate
47+ * SurfaceData representations of a primary SurfaceData.
48+ * The main class will handle tracking the state changes of the
49+ * primary SurfaceData and updating the associated SurfaceData
50+ * proxy variants.
51+ * <p>
52+ * Subclasses have 2 main responsibilities:
53+ * <ul>
54+ * <li> Override the isSupportedOperation() method to determine if
55+ * a given operation can be accelerated with a given source
56+ * SurfaceData
57+ * <li> Override the validateSurfaceData() method to create or update
58+ * a given accelerated surface to hold the pixels for the indicated
59+ * source SurfaceData
60+ * </ul>
61+ * If necessary, a subclass may also override the updateSurfaceData
62+ * method to transfer the pixels to the accelerated surface.
63+ * By default the parent class will transfer the pixels using a
64+ * standard Blit operation between the two SurfaceData objects.
65+ */
66+public abstract class SurfaceDataProxy
67+ implements DisplayChangedListener, SurfaceManager.FlushableCacheData
68+{
69+ private static boolean cachingAllowed;
70+ private static int defaultThreshold;
71+
72+ static {
73+ cachingAllowed = true;
74+ String manimg = (String)AccessController.doPrivileged(
75+ new GetPropertyAction("sun.java2d.managedimages"));
76+ if (manimg != null && manimg.equals("false")) {
77+ cachingAllowed = false;
78+ System.out.println("Disabling managed images");
79+ }
80+
81+ defaultThreshold = 1;
82+ String num = (String)AccessController.doPrivileged(
83+ new GetPropertyAction("sun.java2d.accthreshold"));
84+ if (num != null) {
85+ try {
86+ int parsed = Integer.parseInt(num);
87+ if (parsed >= 0) {
88+ defaultThreshold = parsed;
89+ System.out.println("New Default Acceleration Threshold: " +
90+ defaultThreshold);
91+ }
92+ } catch (NumberFormatException e) {
93+ System.err.println("Error setting new threshold:" + e);
94+ }
95+ }
96+ }
97+
98+ public static boolean isCachingAllowed() {
99+ return cachingAllowed;
100+ }
101+
102+ /**
103+ * Determine if an alternate form for the srcData is needed
104+ * and appropriate from the given operational parameters.
105+ */
106+ public abstract boolean isSupportedOperation(SurfaceData srcData,
107+ int txtype,
108+ CompositeType comp,
109+ Color bgColor);
110+
111+ /**
112+ * Construct an alternate form of the given SurfaceData.
113+ * The contents of the returned SurfaceData may be undefined
114+ * since the calling code will take care of updating the
115+ * contents with a subsequent call to updateSurfaceData.
116+ * <p>
117+ * If the method returns null then there was a problem with
118+ * allocating the accelerated surface. The getRetryTracker()
119+ * method will be called to track when to attempt another
120+ * revalidation.
121+ */
122+ public abstract SurfaceData validateSurfaceData(SurfaceData srcData,
123+ SurfaceData cachedData,
124+ int w, int h);
125+
126+ /**
127+ * If the subclass is unable to validate or create a cached
128+ * SurfaceData then this method will be used to get a
129+ * StateTracker object that will indicate when to attempt
130+ * to validate the surface again. Subclasses may return
131+ * trackers which count down an ever increasing threshold
132+ * to provide hysteresis on creating surfaces during low
133+ * memory conditions. The default implementation just waits
134+ * another "threshold" number of accesses before trying again.
135+ */
136+ public StateTracker getRetryTracker(SurfaceData srcData) {
137+ return new CountdownTracker(threshold);
138+ }
139+
140+ public static class CountdownTracker implements StateTracker {
141+ private int countdown;
142+
143+ public CountdownTracker(int threshold) {
144+ this.countdown = threshold;
145+ }
146+
147+ public synchronized boolean isCurrent() {
148+ return (--countdown >= 0);
149+ }
150+ }
151+
152+ /**
153+ * This instance is for cases where a caching implementation
154+ * determines that a particular source image will never need
155+ * to be cached - either the source SurfaceData was of an
156+ * incompatible type, or it was in an UNTRACKABLE state or
157+ * some other factor is discovered that permanently prevents
158+ * acceleration or caching.
159+ * This class optimally implements NOP variants of all necessary
160+ * methods to avoid caching with a minimum of fuss.
161+ */
162+ public static SurfaceDataProxy UNCACHED = new SurfaceDataProxy(0) {
163+ @Override
164+ public boolean isAccelerated() {
165+ return false;
166+ }
167+
168+ @Override
169+ public boolean isSupportedOperation(SurfaceData srcData,
170+ int txtype,
171+ CompositeType comp,
172+ Color bgColor)
173+ {
174+ return false;
175+ }
176+
177+ @Override
178+ public SurfaceData validateSurfaceData(SurfaceData srcData,
179+ SurfaceData cachedData,
180+ int w, int h)
181+ {
182+ throw new InternalError("UNCACHED should never validate SDs");
183+ }
184+
185+ @Override
186+ public SurfaceData replaceData(SurfaceData srcData,
187+ int txtype,
188+ CompositeType comp,
189+ Color bgColor)
190+ {
191+ // Not necessary to override this, but doing so is faster
192+ return srcData;
193+ }
194+ };
195+
196+ // The number of attempts to copy from a STABLE source before
197+ // a cached copy is created or updated.
198+ private int threshold;
199+
200+ /*
201+ * Source tracking data
202+ *
203+ * Every time that srcTracker is out of date we will reset numtries
204+ * to threshold and set the cacheTracker to one that is non-current.
205+ * numtries will then count down to 0 at which point the cacheTracker
206+ * will remind us that we need to update the cachedSD before we can
207+ * use it.
208+ *
209+ * Note that since these fields interrelate we should synchronize
210+ * whenever we update them, but it should be OK to read them
211+ * without synchronization.
212+ */
213+ private StateTracker srcTracker;
214+ private int numtries;
215+
216+ /*
217+ * Cached data
218+ *
219+ * We cache a SurfaceData created by the subclass in cachedSD and
220+ * track its state (isValid and !surfaceLost) in cacheTracker.
221+ *
222+ * Also, when we want to note that cachedSD needs to be updated
223+ * we replace the cacheTracker with a NEVER_CURRENT tracker which
224+ * will cause us to try to revalidate and update the surface on
225+ * next use.
226+ */
227+ private SurfaceData cachedSD;
228+ private StateTracker cacheTracker;
229+
230+ /*
231+ * Are we still the best object to control caching of data
232+ * for the source image?
233+ */
234+ private boolean valid;
235+
236+ /**
237+ * Create a SurfaceData proxy manager that attempts to create
238+ * and cache a variant copy of the source SurfaceData after
239+ * the default threshold number of attempts to copy from the
240+ * STABLE source.
241+ */
242+ public SurfaceDataProxy() {
243+ this(defaultThreshold);
244+ }
245+
246+ /**
247+ * Create a SurfaceData proxy manager that attempts to create
248+ * and cache a variant copy of the source SurfaceData after
249+ * the specified threshold number of attempts to copy from
250+ * the STABLE source.
251+ */
252+ public SurfaceDataProxy(int threshold) {
253+ this.threshold = threshold;
254+
255+ this.srcTracker = StateTracker.NEVER_CURRENT;
256+ // numtries will be reset on first use
257+ this.cacheTracker = StateTracker.NEVER_CURRENT;
258+
259+ this.valid = true;
260+ }
261+
262+ /**
263+ * Returns true iff this SurfaceData proxy is still the best
264+ * way to control caching of the given source on the given
265+ * destination.
266+ */
267+ public boolean isValid() {
268+ return valid;
269+ }
270+
271+ /**
272+ * Sets the valid state to false so that the next time this
273+ * proxy is fetched to generate a replacement SurfaceData,
274+ * the code in SurfaceData knows to replace the proxy first.
275+ */
276+ public void invalidate() {
277+ this.valid = false;
278+ }
279+
280+ /**
281+ * Flush all cached resources as per the FlushableCacheData interface.
282+ * The deaccelerated parameter indicates if the flush is
283+ * happening because the associated surface is no longer
284+ * being accelerated (for instance the acceleration priority
285+ * is set below the threshold needed for acceleration).
286+ * Returns a boolean that indicates if the cached object is
287+ * no longer needed and should be removed from the cache.
288+ */
289+ public boolean flush(boolean deaccelerated) {
290+ if (deaccelerated) {
291+ invalidate();
292+ }
293+ flush();
294+ return !isValid();
295+ }
296+
297+ /**
298+ * Actively flushes (drops and invalidates) the cached surface
299+ * so that it can be reclaimed quickly.
300+ */
301+ public synchronized void flush() {
302+ SurfaceData csd = this.cachedSD;
303+ this.cachedSD = null;
304+ this.cacheTracker = StateTracker.NEVER_CURRENT;
305+ if (csd != null) {
306+ csd.flush();
307+ }
308+ }
309+
310+ /**
311+ * Returns true iff this SurfaceData proxy is still valid
312+ * and if it has a currently cached replacement that is also
313+ * valid and current.
314+ */
315+ public boolean isAccelerated() {
316+ return (isValid() &&
317+ srcTracker.isCurrent() &&
318+ cacheTracker.isCurrent());
319+ }
320+
321+ /**
322+ * This method should be called from subclasses which create
323+ * cached SurfaceData objects that depend on the current
324+ * properties of the display.
325+ */
326+ protected void activateDisplayListener() {
327+ GraphicsEnvironment ge =
328+ GraphicsEnvironment.getLocalGraphicsEnvironment();
329+ // We could have a HeadlessGE at this point, so double-check before
330+ // assuming anything.
331+ // Also, no point in listening to display change events if
332+ // the image is never going to be accelerated.
333+ if (ge instanceof SunGraphicsEnvironment) {
334+ ((SunGraphicsEnvironment)ge).addDisplayChangedListener(this);
335+ }
336+ }
337+
338+ /**
339+ * Invoked when the display mode has changed.
340+ * This method will invalidate and drop the internal cachedSD object.
341+ */
342+ public void displayChanged() {
343+ flush();
344+ }
345+
346+ /**
347+ * Invoked when the palette has changed.
348+ */
349+ public void paletteChanged() {
350+ // We could potentially get away with just resetting cacheTracker
351+ // here but there is a small window of vulnerability in the
352+ // replaceData method where we could be just finished with
353+ // updating the cachedSD when this method is called and even
354+ // though we set a non-current cacheTracker here it will then
355+ // immediately get set to a current one by the thread that is
356+ // updating the cachedSD. It is safer to just replace the
357+ // srcTracker with a non-current version that will trigger a
358+ // full update cycle the next time this proxy is used.
359+ // The downside is having to go through a full threshold count
360+ // before we can update and use our cache again, but palette
361+ // changes should be relatively rare...
362+ this.srcTracker = StateTracker.NEVER_CURRENT;
363+ }
364+
365+ /**
366+ * This method attempts to replace the srcData with a cached version.
367+ * It relies on the subclass to determine if the cached version will
368+ * be useful given the operational parameters.
369+ * This method checks any preexisting cached copy for being "up to date"
370+ * and tries to update it if it is stale or non-existant and the
371+ * appropriate number of accesses have occured since it last was stale.
372+ * <p>
373+ * An outline of the process is as follows:
374+ * <ol>
375+ * <li> Check the operational parameters (txtype, comp, bgColor)
376+ * to make sure that the operation is supported. Return the
377+ * original SurfaceData if the operation cannot be accelerated.
378+ * <li> Check the tracker for the source surface to see if it has
379+ * remained stable since it was last cached. Update the state
380+ * variables to cause both a threshold countdown and an update
381+ * of the cached copy if it is not. (Setting cacheTracker to
382+ * NEVER_CURRENT effectively marks it as "needing to be updated".)
383+ * <li> Check the tracker for the cached copy to see if is still
384+ * valid and up to date. Note that the cacheTracker may be
385+ * non-current if either something happened to the cached copy
386+ * (eg. surfaceLost) or if the source was out of date and the
387+ * cacheTracker was set to NEVER_CURRENT to force an update.
388+ * Decrement the countdown and copy the source to the cache
389+ * as necessary and then update the variables to show that
390+ * the cached copy is stable.
391+ * </ol>
392+ */
393+ public SurfaceData replaceData(SurfaceData srcData,
394+ int txtype,
395+ CompositeType comp,
396+ Color bgColor)
397+ {
398+ if (isSupportedOperation(srcData, txtype, comp, bgColor)) {
399+ // First deal with tracking the source.
400+ if (!srcTracker.isCurrent()) {
401+ synchronized (this) {
402+ this.numtries = threshold;
403+ this.srcTracker = srcData.getStateTracker();
404+ this.cacheTracker = StateTracker.NEVER_CURRENT;
405+ }
406+
407+ if (!srcTracker.isCurrent()) {
408+ // Dynamic or Untrackable (or a very recent modification)
409+ if (srcData.getState() == State.UNTRACKABLE) {
410+ // UNTRACKABLE means we can never cache again.
411+
412+ // Invalidate so we get replaced next time we are used
413+ // (presumably with an UNCACHED proxy).
414+ invalidate();
415+
416+ // Aggressively drop our reference to the cachedSD
417+ // in case this proxy is not consulted again (and
418+ // thus replaced) for a long time.
419+ flush();
420+ }
421+ return srcData;
422+ }
423+ }
424+
425+ // Then deal with checking the validity of the cached SurfaceData
426+ SurfaceData csd = this.cachedSD;
427+ if (!cacheTracker.isCurrent()) {
428+ // Next make sure the dust has settled
429+ synchronized (this) {
430+ if (numtries > 0) {
431+ --numtries;
432+ return srcData;
433+ }
434+ }
435+
436+ Rectangle r = srcData.getBounds();
437+ int w = r.width;
438+ int h = r.height;
439+
440+ // Snapshot the tracker in case it changes while
441+ // we are updating the cached SD...
442+ StateTracker curTracker = srcTracker;
443+
444+ csd = validateSurfaceData(srcData, csd, w, h);
445+ if (csd == null) {
446+ synchronized (this) {
447+ if (curTracker == srcTracker) {
448+ this.cacheTracker = getRetryTracker(srcData);
449+ this.cachedSD = null;
450+ }
451+ }
452+ return srcData;
453+ }
454+
455+ updateSurfaceData(srcData, csd, w, h);
456+ if (!csd.isValid()) {
457+ return srcData;
458+ }
459+
460+ synchronized (this) {
461+ // We only reset these variables if the tracker from
462+ // before the surface update is still in use and current
463+ // Note that we must use a srcTracker that was fetched
464+ // from before the update process to make sure that we
465+ // do not lose some pixel changes in the shuffle.
466+ if (curTracker == srcTracker && curTracker.isCurrent()) {
467+ this.cacheTracker = csd.getStateTracker();
468+ this.cachedSD = csd;
469+ }
470+ }
471+ }
472+
473+ if (csd != null) {
474+ return csd;
475+ }
476+ }
477+
478+ return srcData;
479+ }
480+
481+ /**
482+ * This is the default implementation for updating the cached
483+ * SurfaceData from the source (primary) SurfaceData.
484+ * A simple Blit is used to copy the pixels from the source to
485+ * the destination SurfaceData.
486+ * A subclass can override this implementation if a more complex
487+ * operation is required to update its cached copies.
488+ */
489+ public void updateSurfaceData(SurfaceData srcData,
490+ SurfaceData dstData,
491+ int w, int h)
492+ {
493+ SurfaceType srcType = srcData.getSurfaceType();
494+ SurfaceType dstType = dstData.getSurfaceType();
495+ Blit blit = Blit.getFromCache(srcType,
496+ CompositeType.SrcNoEa,
497+ dstType);
498+ blit.Blit(srcData, dstData,
499+ AlphaComposite.Src, null,
500+ 0, 0, 0, 0, w, h);
501+ dstData.markDirty();
502+ }
503+
504+ /**
505+ * This is an alternate implementation for updating the cached
506+ * SurfaceData from the source (primary) SurfaceData using a
507+ * background color for transparent pixels.
508+ * A simple BlitBg is used to copy the pixels from the source to
509+ * the destination SurfaceData with the specified bgColor.
510+ * A subclass can override the normal updateSurfaceData method
511+ * and call this implementation instead if it wants to use color
512+ * keying for bitmask images.
513+ */
514+ public void updateSurfaceDataBg(SurfaceData srcData,
515+ SurfaceData dstData,
516+ int w, int h, Color bgColor)
517+ {
518+ SurfaceType srcType = srcData.getSurfaceType();
519+ SurfaceType dstType = dstData.getSurfaceType();
520+ BlitBg blitbg = BlitBg.getFromCache(srcType,
521+ CompositeType.SrcNoEa,
522+ dstType);
523+ blitbg.BlitBg(srcData, dstData,
524+ AlphaComposite.Src, null, bgColor.getRGB(),
525+ 0, 0, 0, 0, w, h);
526+ dstData.markDirty();
527+ }
528+}
java/pkg/sun/java2d/SurfaceManagerFactory.class+0−0

Binary file not shown.

java/pkg/sun/java2d/SurfaceManagerFactory.java+91−0
@@ -0,0 +1,91 @@
1+/*
2+ * Copyright (c) 2003, 2008, 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+
26+package sun.java2d;
27+
28+import sun.awt.image.SunVolatileImage;
29+import sun.awt.image.VolatileSurfaceManager;
30+
31+/**
32+ * This factory creates platform specific VolatileSurfaceManager
33+ * implementations.
34+ *
35+ * There are two platform specific SurfaceManagerFactories in OpenJDK,
36+ * UnixSurfaceManagerFactory and WindowsSurfaceManagerFactory.
37+ * The actually used SurfaceManagerFactory is set by the respective platform
38+ * GraphicsEnvironment implementations in the static initializer.
39+ */
40+public abstract class SurfaceManagerFactory {
41+
42+ /**
43+ * The single shared instance.
44+ */
45+ private static SurfaceManagerFactory instance;
46+
47+ /**
48+ * Returns the surface manager factory instance. This returns a factory
49+ * that has been set by {@link #setInstance(SurfaceManagerFactory)}.
50+ *
51+ * @return the surface manager factory
52+ */
53+ public synchronized static SurfaceManagerFactory getInstance() {
54+
55+ if (instance == null) {
56+ throw new IllegalStateException("No SurfaceManagerFactory set.");
57+ }
58+ return instance;
59+ }
60+
61+ /**
62+ * Sets the surface manager factory. This may only be called once, and it
63+ * may not be set back to {@code null} when the factory is already
64+ * instantiated.
65+ *
66+ * @param factory the factory to set
67+ */
68+ public synchronized static void setInstance(SurfaceManagerFactory factory) {
69+
70+ if (factory == null) {
71+ // We don't want to allow setting this to null at any time.
72+ throw new IllegalArgumentException("factory must be non-null");
73+ }
74+
75+ if (instance != null) {
76+ // We don't want to re-set the instance at any time.
77+ throw new IllegalStateException("The surface manager factory is already initialized");
78+ }
79+
80+ instance = factory;
81+ }
82+
83+ /**
84+ * Creates a new instance of a VolatileSurfaceManager given any
85+ * arbitrary SunVolatileImage. An optional context Object can be supplied
86+ * as a way for the caller to pass pipeline-specific context data to
87+ * the VolatileSurfaceManager (such as a backbuffer handle, for example).
88+ */
89+ public abstract VolatileSurfaceManager
90+ createVolatileManager(SunVolatileImage image, Object context);
91+}
java/pkg/sun/java2d/cmm/CMSManager$1.class+0−0

Binary file not shown.

java/pkg/sun/java2d/cmm/CMSManager$CMMTracer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/cmm/CMSManager.class+0−0

Binary file not shown.

java/pkg/sun/java2d/cmm/CMSManager.java+170−0
@@ -0,0 +1,170 @@
1+/*
2+ * Copyright (c) 2006, 2010, 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+
26+package sun.java2d.cmm;
27+
28+import java.awt.color.ColorSpace;
29+import java.awt.color.ICC_Profile;
30+import java.awt.color.CMMException;
31+import java.awt.image.BufferedImage;
32+import java.awt.image.Raster;
33+import java.awt.image.WritableRaster;
34+import java.security.AccessController;
35+import java.security.PrivilegedAction;
36+import sun.security.action.GetPropertyAction;
37+import java.util.ServiceLoader;
38+
39+public class CMSManager {
40+ public static ColorSpace GRAYspace; // These two fields allow access
41+ public static ColorSpace LINEAR_RGBspace; // to java.awt.color.ColorSpace
42+ // private fields from other
43+ // packages. The fields are set
44+ // by java.awt.color.ColorSpace
45+ // and read by
46+ // java.awt.image.ColorModel.
47+
48+ private static PCMM cmmImpl = null;
49+
50+ public static synchronized PCMM getModule() {
51+ if (cmmImpl != null) {
52+ return cmmImpl;
53+ }
54+
55+ cmmImpl = (PCMM)AccessController.doPrivileged(new PrivilegedAction() {
56+ public Object run() {
57+ String cmmClass = System.getProperty(
58+ "sun.java2d.cmm", "sun.java2d.cmm.kcms.CMM");
59+
60+ ServiceLoader<PCMM> cmmLoader
61+ = ServiceLoader.loadInstalled(PCMM.class);
62+
63+ PCMM service = null;
64+
65+ for (PCMM cmm : cmmLoader) {
66+ service = cmm;
67+ if (cmm.getClass().getName().equals(cmmClass)) {
68+ break;
69+ }
70+ }
71+ return service;
72+ }
73+ });
74+
75+ if (cmmImpl == null) {
76+ throw new CMMException("Cannot initialize Color Management System."+
77+ "No CM module found");
78+ }
79+
80+ GetPropertyAction gpa = new GetPropertyAction("sun.java2d.cmm.trace");
81+ String cmmTrace = (String)AccessController.doPrivileged(gpa);
82+ if (cmmTrace != null) {
83+ cmmImpl = new CMMTracer(cmmImpl);
84+ }
85+
86+ return cmmImpl;
87+ }
88+
89+ /* CMM trace routines */
90+
91+ public static class CMMTracer implements PCMM {
92+ PCMM tcmm;
93+ String cName ;
94+
95+ public CMMTracer(PCMM tcmm) {
96+ this.tcmm = tcmm;
97+ cName = tcmm.getClass().getName();
98+ }
99+
100+ public long loadProfile(byte[] data) {
101+ System.err.print(cName + ".loadProfile");
102+ long profileID = tcmm.loadProfile(data);
103+ System.err.printf("(ID=%x)\n", profileID);
104+ return profileID;
105+ }
106+
107+ public void freeProfile(long profileID) {
108+ System.err.printf(cName + ".freeProfile(ID=%x)\n", profileID);
109+ tcmm.freeProfile(profileID);
110+ }
111+
112+ public int getProfileSize(long profileID) {
113+ System.err.print(cName + ".getProfileSize(ID=" + profileID + ")");
114+ int size = tcmm.getProfileSize(profileID);
115+ System.err.println("=" + size);
116+ return size;
117+ }
118+
119+ public void getProfileData(long profileID, byte[] data) {
120+ System.err.print(cName + ".getProfileData(ID=" + profileID + ") ");
121+ System.err.println("requested " + data.length + " byte(s)");
122+ tcmm.getProfileData(profileID, data);
123+ }
124+
125+ public int getTagSize(long profileID, int tagSignature) {
126+ System.err.printf(cName + ".getTagSize(ID=%x, TagSig=%s)",
127+ profileID, signatureToString(tagSignature));
128+ int size = tcmm.getTagSize(profileID, tagSignature);
129+ System.err.println("=" + size);
130+ return size;
131+ }
132+
133+ public void getTagData(long profileID, int tagSignature,
134+ byte[] data) {
135+ System.err.printf(cName + ".getTagData(ID=%x, TagSig=%s)",
136+ profileID, signatureToString(tagSignature));
137+ System.err.println(" requested " + data.length + " byte(s)");
138+ tcmm.getTagData(profileID, tagSignature, data);
139+ }
140+
141+ public void setTagData(long profileID, int tagSignature,
142+ byte[] data) {
143+ System.err.print(cName + ".setTagData(ID=" + profileID +
144+ ", TagSig=" + tagSignature + ")");
145+ System.err.println(" sending " + data.length + " byte(s)");
146+ tcmm.setTagData(profileID, tagSignature, data);
147+ }
148+
149+ /* methods for creating ColorTransforms */
150+ public ColorTransform createTransform(ICC_Profile profile,
151+ int renderType,
152+ int transformType) {
153+ System.err.println(cName + ".createTransform(ICC_Profile,int,int)");
154+ return tcmm.createTransform(profile, renderType, transformType);
155+ }
156+
157+ public ColorTransform createTransform(ColorTransform[] transforms) {
158+ System.err.println(cName + ".createTransform(ColorTransform[])");
159+ return tcmm.createTransform(transforms);
160+ }
161+
162+ private static String signatureToString(int sig) {
163+ return String.format("%c%c%c%c",
164+ (char)(0xff & (sig >> 24)),
165+ (char)(0xff & (sig >> 16)),
166+ (char)(0xff & (sig >> 8)),
167+ (char)(0xff & (sig )));
168+ }
169+ }
170+}
java/pkg/sun/java2d/cmm/ColorTransform.class+0−0

Binary file not shown.

java/pkg/sun/java2d/cmm/ColorTransform.java+53−0
@@ -0,0 +1,53 @@
1+/*
2+ * Copyright (c) 2006, 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+
26+package sun.java2d.cmm;
27+
28+import java.awt.image.BufferedImage;
29+import java.awt.image.Raster;
30+import java.awt.image.WritableRaster;
31+
32+public interface ColorTransform {
33+ public int Any = -1;/* any rendering type, whichever is
34+ available */
35+ /* search order is icPerceptual,
36+ icRelativeColorimetric, icSaturation */
37+
38+ /* Transform types */
39+ public int In = 1;
40+ public int Out = 2;
41+ public int Gamut = 3;
42+ public int Simulation = 4;
43+
44+ public int getNumInComponents();
45+ public int getNumOutComponents();
46+ public void colorConvert(BufferedImage src, BufferedImage dst);
47+ public void colorConvert(Raster src, WritableRaster dst,
48+ float[] srcMinVal, float[]srcMaxVal,
49+ float[] dstMinVal, float[]dstMaxVal);
50+ public void colorConvert(Raster src, WritableRaster dst);
51+ public short[] colorConvert(short[] src, short[] dest);
52+ public byte[] colorConvert (byte[] src, byte[] dest);
53+}
java/pkg/sun/java2d/cmm/PCMM.class+0−0

Binary file not shown.

java/pkg/sun/java2d/cmm/PCMM.java+48−0
@@ -0,0 +1,48 @@
1+/*
2+ * Copyright (c) 2006, 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+
26+package sun.java2d.cmm;
27+
28+import java.awt.color.ICC_Profile;
29+
30+/* Pluggable CMM interface */
31+
32+public interface PCMM {
33+
34+ /* methods invoked from ICC_Profile */
35+ public long loadProfile(byte[] data);
36+ public void freeProfile(long profileID);
37+ public int getProfileSize(long profileID);
38+ public void getProfileData(long profileID, byte[] data);
39+ public void getTagData(long profileID, int tagSignature, byte[] data);
40+ public int getTagSize(long profileID, int tagSignature);
41+ public void setTagData(long profileID, int tagSignature, byte[] data);
42+
43+ /* methods for creating ColorTransforms */
44+ public ColorTransform createTransform(ICC_Profile profile, int renderType,
45+ int transformType);
46+
47+ public ColorTransform createTransform(ColorTransform[] transforms);
48+}
java/pkg/sun/java2d/cmm/ProfileActivator.class+0−0

Binary file not shown.

java/pkg/sun/java2d/cmm/ProfileActivator.java+41−0
@@ -0,0 +1,41 @@
1+/*
2+ * Copyright (c) 1998, 2006, 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+
26+package sun.java2d.cmm;
27+
28+import java.awt.color.ProfileDataException;
29+
30+/**
31+ * An interface to allow the ProfileDeferralMgr to activate a
32+ * deferred profile.
33+ */
34+public interface ProfileActivator {
35+
36+ /**
37+ * Activate a previously deferred ICC_Profile object.
38+ */
39+ public void activate() throws ProfileDataException;
40+
41+}
java/pkg/sun/java2d/cmm/ProfileDeferralInfo.class+0−0

Binary file not shown.

java/pkg/sun/java2d/cmm/ProfileDeferralInfo.java+61−0
@@ -0,0 +1,61 @@
1+/*
2+ * Copyright (c) 1998, 2006, 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+
26+package sun.java2d.cmm;
27+
28+import java.io.InputStream;
29+import java.io.IOException;
30+
31+
32+/**
33+ * A class to pass information about a profile to be loaded from
34+ * a file to the static getInstance(InputStream) method of
35+ * ICC_Profile. Loading of the profile data and initialization
36+ * of the CMM is to be deferred as long as possible.
37+ */
38+public class ProfileDeferralInfo extends InputStream {
39+
40+ public int colorSpaceType, numComponents, profileClass;
41+ public String filename;
42+
43+ public ProfileDeferralInfo(String fn, int type, int ncomp, int pclass) {
44+
45+ super();
46+ filename = fn;
47+ colorSpaceType = type;
48+ numComponents = ncomp;
49+ profileClass = pclass;
50+ }
51+
52+
53+ /**
54+ * Implements the abstract read() method of InputStream.
55+ */
56+ public int read() throws IOException {
57+
58+ return 0;
59+ }
60+
61+}
java/pkg/sun/java2d/cmm/ProfileDeferralMgr.class+0−0

Binary file not shown.

java/pkg/sun/java2d/cmm/ProfileDeferralMgr.java+119−0
@@ -0,0 +1,119 @@
1+/*
2+ * Copyright (c) 1998, 2006, 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+
26+package sun.java2d.cmm;
27+
28+import java.awt.color.ProfileDataException;
29+import java.util.Vector;
30+
31+
32+/**
33+ * A class to manage the deferral of CMM initialization of profile
34+ * data for internal ICC_Profile objects - i.e. when we "trust" that
35+ * the profile data is valid and we think it may not be needed. An
36+ * example is the sRGB profile which gets loaded by any program doing
37+ * graphics, but which may not be needed if the program does not need
38+ * high quality color conversion.
39+ */
40+public class ProfileDeferralMgr {
41+
42+ public static boolean deferring = true;
43+ private static Vector<ProfileActivator> aVector;
44+
45+ /**
46+ * Records a ProfileActivator object whose activate method will
47+ * be called if the CMM needs to be activated.
48+ */
49+ public static void registerDeferral(ProfileActivator pa) {
50+
51+ if (!deferring) {
52+ return;
53+ }
54+ if (aVector == null) {
55+ aVector = new Vector<ProfileActivator>(3, 3);
56+ }
57+ aVector.addElement(pa);
58+ return;
59+ }
60+
61+
62+ /**
63+ * Removes a ProfileActivator object from the vector of ProfileActivator
64+ * objects whose activate method will be called if the CMM needs to be
65+ * activated.
66+ */
67+ public static void unregisterDeferral(ProfileActivator pa) {
68+
69+ if (!deferring) {
70+ return;
71+ }
72+ if (aVector == null) {
73+ return;
74+ }
75+ aVector.removeElement(pa);
76+ return;
77+ }
78+
79+ /**
80+ * Removes a ProfileActivator object from the vector of ProfileActivator
81+ * objects whose activate method will be called if the CMM needs to be
82+ * activated.
83+ */
84+ public static void activateProfiles() {
85+
86+ int i, n;
87+
88+ deferring = false;
89+ if (aVector == null) {
90+ return;
91+ }
92+ n = aVector.size();
93+ for (ProfileActivator pa : aVector) {
94+ try {
95+ pa.activate();
96+ } catch (ProfileDataException e) {
97+ /*
98+ * Ignore profile activation error for now:
99+ * such exception is pssible due to absence
100+ * or corruption of standard color profile.
101+ * As for now we expect all profiles should
102+ * be shiped with jre and presence of this
103+ * exception is indication of some configuration
104+ * problem in jre installation.
105+ *
106+ * NB: we still are greedy loading deferred profiles
107+ * and load them all if any of them is needed.
108+ * Therefore broken profile (if any) might be never used.
109+ * If there will be attempt to use broken profile then
110+ * it will result in CMMException.
111+ */
112+ }
113+ }
114+ aVector.removeAllElements();
115+ aVector = null;
116+ return;
117+ }
118+
119+}
java/pkg/sun/java2d/cmm/lcms/LCMS.java+104−0
@@ -0,0 +1,104 @@
1+/*
2+ * Copyright (c) 2007, 2010, 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+
26+package sun.java2d.cmm.lcms;
27+
28+import java.awt.color.ColorSpace;
29+import java.awt.color.ICC_Profile;
30+import java.awt.color.CMMException;
31+import sun.java2d.cmm.ColorTransform;
32+import sun.java2d.cmm.PCMM;
33+import sun.java2d.cmm.lcms.LCMS;
34+import sun.java2d.cmm.lcms.LCMSTransform;
35+
36+public class LCMS implements PCMM {
37+
38+ /* methods invoked from ICC_Profile */
39+ public native long loadProfile(byte[] data);
40+
41+ public native void freeProfile(long profileID);
42+
43+ public native synchronized int getProfileSize(long profileID);
44+
45+ public native synchronized void getProfileData(long profileID, byte[] data);
46+
47+ public native synchronized int getTagSize(long profileID, int tagSignature);
48+ public native synchronized void getTagData(long profileID, int tagSignature,
49+ byte[] data);
50+ public native synchronized void setTagData(long profileID, int tagSignature,
51+ byte[] data);
52+
53+ public static native long getProfileID(ICC_Profile profile);
54+
55+ public static native long createNativeTransform(
56+ long[] profileIDs, int renderType, int inFormatter, int outFormatter,
57+ Object disposerRef);
58+
59+ /**
60+ * Constructs ColorTransform object corresponding to an ICC_profile
61+ */
62+ public ColorTransform createTransform(ICC_Profile profile,
63+ int renderType,
64+ int transformType)
65+ {
66+ return new LCMSTransform(profile, renderType, renderType);
67+ }
68+
69+ /**
70+ * Constructs an ColorTransform object from a list of ColorTransform
71+ * objects
72+ */
73+ public synchronized ColorTransform createTransform(
74+ ColorTransform[] transforms)
75+ {
76+ return new LCMSTransform(transforms);
77+ }
78+
79+ /* methods invoked from LCMSTransform */
80+ public static native void colorConvert(LCMSTransform trans,
81+ LCMSImageLayout src,
82+ LCMSImageLayout dest);
83+ public static native void freeTransform(long ID);
84+
85+ public static native void initLCMS(Class Trans, Class IL, Class Pf);
86+
87+ /* the class initializer which loads the CMM */
88+ static {
89+ java.security.AccessController.doPrivileged(
90+ new java.security.PrivilegedAction() {
91+ public Object run() {
92+ /* We need to load awt here because of usage trace and
93+ * disposer frameworks
94+ */
95+ System.loadLibrary("awt");
96+ System.loadLibrary("lcms");
97+ return null;
98+ }
99+ }
100+ );
101+
102+ initLCMS(LCMSTransform.class, LCMSImageLayout.class, ICC_Profile.class);
103+ }
104+}
java/pkg/sun/java2d/cmm/lcms/LCMSImageLayout.java+235−0
@@ -0,0 +1,235 @@
1+/*
2+ * Copyright (c) 2007, 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+
26+package sun.java2d.cmm.lcms;
27+
28+import java.awt.Graphics2D;
29+import java.awt.image.BufferedImage;
30+import java.awt.image.ComponentColorModel;
31+import java.awt.image.Raster;
32+import java.awt.image.WritableRaster;
33+import java.awt.image.SinglePixelPackedSampleModel;
34+import java.awt.image.ComponentSampleModel;
35+import java.awt.image.DataBuffer;
36+import java.awt.image.DataBufferByte;
37+import java.awt.image.DataBufferUShort;
38+import java.awt.image.DataBufferInt;
39+import java.awt.image.ColorModel;
40+import sun.awt.image.ByteComponentRaster;
41+import sun.awt.image.ShortComponentRaster;
42+import sun.awt.image.IntegerComponentRaster;
43+
44+
45+class LCMSImageLayout {
46+
47+ public static int BYTES_SH(int x) {
48+ return x;
49+ }
50+
51+ public static int EXTRA_SH(int x) {
52+ return x<<7;
53+ }
54+
55+ public static int CHANNELS_SH(int x) {
56+ return x<<3;
57+ }
58+
59+ public static final int SWAPFIRST = 1<<14;
60+
61+ public static final int DOSWAP = 1<<10;
62+
63+ public static final int PT_RGB_8 =
64+ CHANNELS_SH(3) | BYTES_SH(1);
65+
66+ public static final int PT_GRAY_8 =
67+ CHANNELS_SH(1) | BYTES_SH(1);
68+
69+ public static final int PT_GRAY_16 =
70+ CHANNELS_SH(1) | BYTES_SH(2);
71+
72+ public static final int PT_RGBA_8 =
73+ EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1);
74+
75+ public static final int PT_ARGB_8 =
76+ EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1) | SWAPFIRST;
77+
78+ public static final int PT_BGR_8 =
79+ DOSWAP | CHANNELS_SH(3) | BYTES_SH(1);
80+
81+ public static final int PT_ABGR_8 =
82+ DOSWAP | EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1);
83+
84+ public static final int PT_BGRA_8 = EXTRA_SH(1) | CHANNELS_SH(3) |
85+ BYTES_SH(1) | DOSWAP | SWAPFIRST;
86+
87+ public static final int DT_BYTE = 0;
88+ public static final int DT_SHORT = 1;
89+ public static final int DT_INT = 2;
90+ public static final int DT_DOUBLE = 3;
91+
92+
93+ boolean isIntPacked = false;
94+ int pixelType;
95+ int dataType;
96+ int width;
97+ int height;
98+ int nextRowOffset;
99+ int offset;
100+
101+ Object dataArray;
102+ private LCMSImageLayout(int np, int pixelType, int pixelSize) {
103+ this.pixelType = pixelType;
104+ width = np;
105+ height = 1;
106+ nextRowOffset = np*pixelSize;
107+ offset = 0;
108+ }
109+
110+ private LCMSImageLayout(int width, int height, int pixelType,
111+ int pixelSize) {
112+ this.pixelType = pixelType;
113+ this.width = width;
114+ this.height = height;
115+ nextRowOffset = width*pixelSize;
116+ offset = 0;
117+ }
118+
119+
120+ public LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize) {
121+ this(np, pixelType, pixelSize);
122+ dataType = DT_BYTE;
123+ dataArray = data;
124+ }
125+
126+ public LCMSImageLayout(short[] data, int np, int pixelType, int pixelSize) {
127+ this(np, pixelType, pixelSize);
128+ dataType = DT_SHORT;
129+ dataArray = data;
130+ }
131+
132+ public LCMSImageLayout(int[] data, int np, int pixelType, int pixelSize) {
133+ this(np, pixelType, pixelSize);
134+ dataType = DT_INT;
135+ dataArray = data;
136+ }
137+
138+ public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize)
139+ {
140+ this(np, pixelType, pixelSize);
141+ dataType = DT_DOUBLE;
142+ dataArray = data;
143+ }
144+
145+ public LCMSImageLayout(BufferedImage image) {
146+ ShortComponentRaster shortRaster;
147+ IntegerComponentRaster intRaster;
148+ ByteComponentRaster byteRaster;
149+ switch (image.getType()) {
150+ case BufferedImage.TYPE_INT_RGB:
151+ pixelType = PT_ARGB_8;
152+ isIntPacked = true;
153+ break;
154+ case BufferedImage.TYPE_INT_ARGB:
155+ pixelType = PT_ARGB_8;
156+ isIntPacked = true;
157+ break;
158+ case BufferedImage.TYPE_INT_BGR:
159+ pixelType = PT_ABGR_8;
160+ isIntPacked = true;
161+ break;
162+ case BufferedImage.TYPE_3BYTE_BGR:
163+ pixelType = PT_BGR_8;
164+ break;
165+ case BufferedImage.TYPE_4BYTE_ABGR:
166+ pixelType = PT_ABGR_8;
167+ break;
168+ case BufferedImage.TYPE_BYTE_GRAY:
169+ pixelType = PT_GRAY_8;
170+ break;
171+ case BufferedImage.TYPE_USHORT_GRAY:
172+ pixelType = PT_GRAY_16;
173+ break;
174+ default:
175+ // TODO: Add support for some images having
176+ // SinglePixelPackedModel and ComponentSampleModel
177+ throw new IllegalArgumentException(
178+ "CMMImageLayout - bad image type passed to constructor");
179+ }
180+
181+ width = image.getWidth();
182+ height = image.getHeight();
183+
184+ switch (image.getType()) {
185+ case BufferedImage.TYPE_INT_RGB:
186+ case BufferedImage.TYPE_INT_ARGB:
187+ case BufferedImage.TYPE_INT_BGR:
188+ intRaster = (IntegerComponentRaster)image.getRaster();
189+ nextRowOffset = intRaster.getScanlineStride()*4;
190+ offset = intRaster.getDataOffset(0)*4;
191+ dataArray = intRaster.getDataStorage();
192+ dataType = DT_INT;
193+ break;
194+
195+ case BufferedImage.TYPE_3BYTE_BGR:
196+ case BufferedImage.TYPE_4BYTE_ABGR:
197+ byteRaster = (ByteComponentRaster)image.getRaster();
198+ nextRowOffset = byteRaster.getScanlineStride();
199+ offset = byteRaster.getDataOffset(0);
200+ dataArray = byteRaster.getDataStorage();
201+ dataType = DT_BYTE;
202+ break;
203+
204+ case BufferedImage.TYPE_BYTE_GRAY:
205+ byteRaster = (ByteComponentRaster)image.getRaster();
206+ nextRowOffset = byteRaster.getScanlineStride();
207+ offset = byteRaster.getDataOffset(0);
208+ dataArray = byteRaster.getDataStorage();
209+ dataType = DT_BYTE;
210+ break;
211+
212+ case BufferedImage.TYPE_USHORT_GRAY:
213+ shortRaster = (ShortComponentRaster)image.getRaster();
214+ nextRowOffset = shortRaster.getScanlineStride()*2;
215+ offset = shortRaster.getDataOffset(0) * 2;
216+ dataArray = shortRaster.getDataStorage();
217+ dataType = DT_SHORT;
218+ break;
219+ }
220+ }
221+
222+ public static boolean isSupported(BufferedImage image) {
223+ switch (image.getType()) {
224+ case BufferedImage.TYPE_INT_RGB:
225+ case BufferedImage.TYPE_INT_ARGB:
226+ case BufferedImage.TYPE_INT_BGR:
227+ case BufferedImage.TYPE_3BYTE_BGR:
228+ case BufferedImage.TYPE_4BYTE_ABGR:
229+ case BufferedImage.TYPE_BYTE_GRAY:
230+ case BufferedImage.TYPE_USHORT_GRAY:
231+ return true;
232+ }
233+ return false;
234+ }
235+}
java/pkg/sun/java2d/cmm/lcms/LCMSTransform.java+609−0
@@ -0,0 +1,609 @@
1+/*
2+ * Copyright (c) 2007, 2010, 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+
26+/**********************************************************************
27+ **********************************************************************
28+ **********************************************************************
29+ *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
30+ *** As an unpublished work pursuant to Title 17 of the United ***
31+ *** States Code. All rights reserved. ***
32+ **********************************************************************
33+ **********************************************************************
34+ **********************************************************************/
35+
36+package sun.java2d.cmm.lcms;
37+
38+import java.awt.color.ICC_Profile;
39+import java.awt.color.ProfileDataException;
40+import java.awt.color.CMMException;
41+import java.awt.color.ColorSpace;
42+import java.awt.image.BufferedImage;
43+import java.awt.image.Raster;
44+import java.awt.image.WritableRaster;
45+import java.awt.image.ColorModel;
46+import java.awt.image.DirectColorModel;
47+import java.awt.image.ComponentColorModel;
48+import java.awt.image.SampleModel;
49+import java.awt.image.DataBuffer;
50+import java.awt.image.SinglePixelPackedSampleModel;
51+import java.awt.image.ComponentSampleModel;
52+import sun.java2d.cmm.*;
53+import sun.java2d.cmm.lcms.*;
54+
55+
56+public class LCMSTransform implements ColorTransform {
57+ long ID;
58+ private int inFormatter;
59+ private int outFormatter;
60+
61+ ICC_Profile[] profiles;
62+ long [] profileIDs;
63+ int renderType;
64+ int transformType;
65+
66+ private int numInComponents = -1;
67+ private int numOutComponents = -1;
68+
69+ private Object disposerReferent = new Object();
70+
71+ /* the class initializer */
72+ static {
73+ if (ProfileDeferralMgr.deferring) {
74+ ProfileDeferralMgr.activateProfiles();
75+ }
76+ }
77+
78+ public LCMSTransform(ICC_Profile profile, int renderType,
79+ int transformType)
80+ {
81+ /* Actually, it is not a complete transform but just part of it */
82+ profiles = new ICC_Profile[1];
83+ profiles[0] = profile;
84+ profileIDs = new long[1];
85+ profileIDs[0] = LCMS.getProfileID(profile);
86+ this.renderType = (renderType == ColorTransform.Any)?
87+ ICC_Profile.icPerceptual : renderType;
88+ this.transformType = transformType;
89+
90+ /* Note that ICC_Profile.getNumComponents() is quite expensive
91+ * (it may results in a reading of the profile header).
92+ * So, here we cache the number of components of input and
93+ * output profiles for further usage.
94+ */
95+ numInComponents = profiles[0].getNumComponents();
96+ numOutComponents = profiles[profiles.length - 1].getNumComponents();
97+ }
98+
99+ public LCMSTransform (ColorTransform[] transforms) {
100+ int size = 0;
101+ for (int i=0; i < transforms.length; i++) {
102+ size+=((LCMSTransform)transforms[i]).profiles.length;
103+ }
104+ profiles = new ICC_Profile[size];
105+ profileIDs = new long[size];
106+ int j = 0;
107+ for (int i=0; i < transforms.length; i++) {
108+ LCMSTransform curTrans = (LCMSTransform)transforms[i];
109+ System.arraycopy(curTrans.profiles, 0, profiles, j,
110+ curTrans.profiles.length);
111+ System.arraycopy(curTrans.profileIDs, 0, profileIDs, j,
112+ curTrans.profileIDs.length);
113+ j += curTrans.profiles.length;
114+ }
115+ renderType = ((LCMSTransform)transforms[0]).renderType;
116+
117+ /* Note that ICC_Profile.getNumComponents() is quite expensive
118+ * (it may results in a reading of the profile header).
119+ * So, here we cache the number of components of input and
120+ * output profiles for further usage.
121+ */
122+ numInComponents = profiles[0].getNumComponents();
123+ numOutComponents = profiles[profiles.length - 1].getNumComponents();
124+ }
125+
126+ public int getNumInComponents() {
127+ return numInComponents;
128+ }
129+
130+ public int getNumOutComponents() {
131+ return numOutComponents;
132+ }
133+
134+ private synchronized void doTransform(LCMSImageLayout in,
135+ LCMSImageLayout out) {
136+ // update native transfrom if needed
137+ if (ID == 0L ||
138+ inFormatter != in.pixelType ||
139+ outFormatter != out.pixelType) {
140+
141+ if (ID != 0L) {
142+ // Disposer will destroy forgotten transform
143+ disposerReferent = new Object();
144+ }
145+ inFormatter = in.pixelType;
146+ outFormatter = out.pixelType;
147+
148+ ID = LCMS.createNativeTransform(profileIDs, renderType,
149+ inFormatter, outFormatter,
150+ disposerReferent);
151+ }
152+
153+ LCMS.colorConvert(this, in, out);
154+ }
155+
156+ public void colorConvert(BufferedImage src, BufferedImage dst) {
157+ if (LCMSImageLayout.isSupported(src) &&
158+ LCMSImageLayout.isSupported(dst))
159+ {
160+ doTransform(new LCMSImageLayout(src), new LCMSImageLayout(dst));
161+ return;
162+ }
163+ LCMSImageLayout srcIL, dstIL;
164+ Raster srcRas = src.getRaster();
165+ WritableRaster dstRas = dst.getRaster();
166+ ColorModel srcCM = src.getColorModel();
167+ ColorModel dstCM = dst.getColorModel();
168+ int w = src.getWidth();
169+ int h = src.getHeight();
170+ int srcNumComp = srcCM.getNumColorComponents();
171+ int dstNumComp = dstCM.getNumColorComponents();
172+ int precision = 8;
173+ float maxNum = 255.0f;
174+ for (int i = 0; i < srcNumComp; i++) {
175+ if (srcCM.getComponentSize(i) > 8) {
176+ precision = 16;
177+ maxNum = 65535.0f;
178+ }
179+ }
180+ for (int i = 0; i < dstNumComp; i++) {
181+ if (dstCM.getComponentSize(i) > 8) {
182+ precision = 16;
183+ maxNum = 65535.0f;
184+ }
185+ }
186+ float[] srcMinVal = new float[srcNumComp];
187+ float[] srcInvDiffMinMax = new float[srcNumComp];
188+ ColorSpace cs = srcCM.getColorSpace();
189+ for (int i = 0; i < srcNumComp; i++) {
190+ srcMinVal[i] = cs.getMinValue(i);
191+ srcInvDiffMinMax[i] = maxNum / (cs.getMaxValue(i) - srcMinVal[i]);
192+ }
193+ cs = dstCM.getColorSpace();
194+ float[] dstMinVal = new float[dstNumComp];
195+ float[] dstDiffMinMax = new float[dstNumComp];
196+ for (int i = 0; i < dstNumComp; i++) {
197+ dstMinVal[i] = cs.getMinValue(i);
198+ dstDiffMinMax[i] = (cs.getMaxValue(i) - dstMinVal[i]) / maxNum;
199+ }
200+ boolean dstHasAlpha = dstCM.hasAlpha();
201+ boolean needSrcAlpha = srcCM.hasAlpha() && dstHasAlpha;
202+ float[] dstColor;
203+ if (dstHasAlpha) {
204+ dstColor = new float[dstNumComp + 1];
205+ } else {
206+ dstColor = new float[dstNumComp];
207+ }
208+ if (precision == 8) {
209+ byte[] srcLine = new byte[w * srcNumComp];
210+ byte[] dstLine = new byte[w * dstNumComp];
211+ Object pixel;
212+ float[] color;
213+ float[] alpha = null;
214+ if (needSrcAlpha) {
215+ alpha = new float[w];
216+ }
217+ int idx;
218+ // TODO check for src npixels = dst npixels
219+ srcIL = new LCMSImageLayout(
220+ srcLine, srcLine.length/getNumInComponents(),
221+ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
222+ LCMSImageLayout.BYTES_SH(1), getNumInComponents());
223+ dstIL = new LCMSImageLayout(
224+ dstLine, dstLine.length/getNumOutComponents(),
225+ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
226+ LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
227+ // process each scanline
228+ for (int y = 0; y < h; y++) {
229+ // convert src scanline
230+ pixel = null;
231+ color = null;
232+ idx = 0;
233+ for (int x = 0; x < w; x++) {
234+ pixel = srcRas.getDataElements(x, y, pixel);
235+ color = srcCM.getNormalizedComponents(pixel, color, 0);
236+ for (int i = 0; i < srcNumComp; i++) {
237+ srcLine[idx++] = (byte)
238+ ((color[i] - srcMinVal[i]) * srcInvDiffMinMax[i] +
239+ 0.5f);
240+ }
241+ if (needSrcAlpha) {
242+ alpha[x] = color[srcNumComp];
243+ }
244+ }
245+ // color convert srcLine to dstLine
246+ doTransform(srcIL, dstIL);
247+
248+ // convert dst scanline
249+ pixel = null;
250+ idx = 0;
251+ for (int x = 0; x < w; x++) {
252+ for (int i = 0; i < dstNumComp; i++) {
253+ dstColor[i] = ((float) (dstLine[idx++] & 0xff)) *
254+ dstDiffMinMax[i] + dstMinVal[i];
255+ }
256+ if (needSrcAlpha) {
257+ dstColor[dstNumComp] = alpha[x];
258+ } else if (dstHasAlpha) {
259+ dstColor[dstNumComp] = 1.0f;
260+ }
261+ pixel = dstCM.getDataElements(dstColor, 0, pixel);
262+ dstRas.setDataElements(x, y, pixel);
263+ }
264+ }
265+ } else {
266+ short[] srcLine = new short[w * srcNumComp];
267+ short[] dstLine = new short[w * dstNumComp];
268+ Object pixel;
269+ float[] color;
270+ float[] alpha = null;
271+ if (needSrcAlpha) {
272+ alpha = new float[w];
273+ }
274+ int idx;
275+ srcIL = new LCMSImageLayout(
276+ srcLine, srcLine.length/getNumInComponents(),
277+ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
278+ LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
279+
280+ dstIL = new LCMSImageLayout(
281+ dstLine, dstLine.length/getNumOutComponents(),
282+ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
283+ LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
284+
285+ // process each scanline
286+ for (int y = 0; y < h; y++) {
287+ // convert src scanline
288+ pixel = null;
289+ color = null;
290+ idx = 0;
291+ for (int x = 0; x < w; x++) {
292+ pixel = srcRas.getDataElements(x, y, pixel);
293+ color = srcCM.getNormalizedComponents(pixel, color, 0);
294+ for (int i = 0; i < srcNumComp; i++) {
295+ srcLine[idx++] = (short)
296+ ((color[i] - srcMinVal[i]) * srcInvDiffMinMax[i] +
297+ 0.5f);
298+ }
299+ if (needSrcAlpha) {
300+ alpha[x] = color[srcNumComp];
301+ }
302+ }
303+ // color convert srcLine to dstLine
304+ doTransform(srcIL, dstIL);
305+
306+ // convert dst scanline
307+ pixel = null;
308+ idx = 0;
309+ for (int x = 0; x < w; x++) {
310+ for (int i = 0; i < dstNumComp; i++) {
311+ dstColor[i] = ((float) (dstLine[idx++] & 0xffff)) *
312+ dstDiffMinMax[i] + dstMinVal[i];
313+ }
314+ if (needSrcAlpha) {
315+ dstColor[dstNumComp] = alpha[x];
316+ } else if (dstHasAlpha) {
317+ dstColor[dstNumComp] = 1.0f;
318+ }
319+ pixel = dstCM.getDataElements(dstColor, 0, pixel);
320+ dstRas.setDataElements(x, y, pixel);
321+ }
322+ }
323+ }
324+ }
325+
326+ public void colorConvert(Raster src, WritableRaster dst,
327+ float[] srcMinVal, float[]srcMaxVal,
328+ float[] dstMinVal, float[]dstMaxVal) {
329+ LCMSImageLayout srcIL, dstIL;
330+
331+ // Can't pass src and dst directly to CMM, so process per scanline
332+ SampleModel srcSM = src.getSampleModel();
333+ SampleModel dstSM = dst.getSampleModel();
334+ int srcTransferType = src.getTransferType();
335+ int dstTransferType = dst.getTransferType();
336+ boolean srcIsFloat, dstIsFloat;
337+ if ((srcTransferType == DataBuffer.TYPE_FLOAT) ||
338+ (srcTransferType == DataBuffer.TYPE_DOUBLE)) {
339+ srcIsFloat = true;
340+ } else {
341+ srcIsFloat = false;
342+ }
343+ if ((dstTransferType == DataBuffer.TYPE_FLOAT) ||
344+ (dstTransferType == DataBuffer.TYPE_DOUBLE)) {
345+ dstIsFloat = true;
346+ } else {
347+ dstIsFloat = false;
348+ }
349+ int w = src.getWidth();
350+ int h = src.getHeight();
351+ int srcNumBands = src.getNumBands();
352+ int dstNumBands = dst.getNumBands();
353+ float[] srcScaleFactor = new float[srcNumBands];
354+ float[] dstScaleFactor = new float[dstNumBands];
355+ float[] srcUseMinVal = new float[srcNumBands];
356+ float[] dstUseMinVal = new float[dstNumBands];
357+ for (int i = 0; i < srcNumBands; i++) {
358+ if (srcIsFloat) {
359+ srcScaleFactor[i] = 65535.0f / (srcMaxVal[i] - srcMinVal[i]);
360+ srcUseMinVal[i] = srcMinVal[i];
361+ } else {
362+ if (srcTransferType == DataBuffer.TYPE_SHORT) {
363+ srcScaleFactor[i] = 65535.0f / 32767.0f;
364+ } else {
365+ srcScaleFactor[i] = 65535.0f /
366+ ((float) ((1 << srcSM.getSampleSize(i)) - 1));
367+ }
368+ srcUseMinVal[i] = 0.0f;
369+ }
370+ }
371+ for (int i = 0; i < dstNumBands; i++) {
372+ if (dstIsFloat) {
373+ dstScaleFactor[i] = (dstMaxVal[i] - dstMinVal[i]) / 65535.0f;
374+ dstUseMinVal[i] = dstMinVal[i];
375+ } else {
376+ if (dstTransferType == DataBuffer.TYPE_SHORT) {
377+ dstScaleFactor[i] = 32767.0f / 65535.0f;
378+ } else {
379+ dstScaleFactor[i] =
380+ ((float) ((1 << dstSM.getSampleSize(i)) - 1)) /
381+ 65535.0f;
382+ }
383+ dstUseMinVal[i] = 0.0f;
384+ }
385+ }
386+ int ys = src.getMinY();
387+ int yd = dst.getMinY();
388+ int xs, xd;
389+ float sample;
390+ short[] srcLine = new short[w * srcNumBands];
391+ short[] dstLine = new short[w * dstNumBands];
392+ int idx;
393+ srcIL = new LCMSImageLayout(
394+ srcLine, srcLine.length/getNumInComponents(),
395+ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
396+ LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
397+
398+ dstIL = new LCMSImageLayout(
399+ dstLine, dstLine.length/getNumOutComponents(),
400+ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
401+ LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
402+
403+ // process each scanline
404+ for (int y = 0; y < h; y++, ys++, yd++) {
405+ // get src scanline
406+ xs = src.getMinX();
407+ idx = 0;
408+ for (int x = 0; x < w; x++, xs++) {
409+ for (int i = 0; i < srcNumBands; i++) {
410+ sample = src.getSampleFloat(xs, ys, i);
411+ srcLine[idx++] = (short)
412+ ((sample - srcUseMinVal[i]) * srcScaleFactor[i] + 0.5f);
413+ }
414+ }
415+
416+ // color convert srcLine to dstLine
417+ doTransform(srcIL, dstIL);
418+
419+ // store dst scanline
420+ xd = dst.getMinX();
421+ idx = 0;
422+ for (int x = 0; x < w; x++, xd++) {
423+ for (int i = 0; i < dstNumBands; i++) {
424+ sample = ((dstLine[idx++] & 0xffff) * dstScaleFactor[i]) +
425+ dstUseMinVal[i];
426+ dst.setSample(xd, yd, i, sample);
427+ }
428+ }
429+ }
430+ }
431+
432+ public void colorConvert(Raster src, WritableRaster dst) {
433+
434+ LCMSImageLayout srcIL, dstIL;
435+ // Can't pass src and dst directly to CMM, so process per scanline
436+ SampleModel srcSM = src.getSampleModel();
437+ SampleModel dstSM = dst.getSampleModel();
438+ int srcTransferType = src.getTransferType();
439+ int dstTransferType = dst.getTransferType();
440+ int w = src.getWidth();
441+ int h = src.getHeight();
442+ int srcNumBands = src.getNumBands();
443+ int dstNumBands = dst.getNumBands();
444+ int precision = 8;
445+ float maxNum = 255.0f;
446+ for (int i = 0; i < srcNumBands; i++) {
447+ if (srcSM.getSampleSize(i) > 8) {
448+ precision = 16;
449+ maxNum = 65535.0f;
450+ }
451+ }
452+ for (int i = 0; i < dstNumBands; i++) {
453+ if (dstSM.getSampleSize(i) > 8) {
454+ precision = 16;
455+ maxNum = 65535.0f;
456+ }
457+ }
458+ float[] srcScaleFactor = new float[srcNumBands];
459+ float[] dstScaleFactor = new float[dstNumBands];
460+ for (int i = 0; i < srcNumBands; i++) {
461+ if (srcTransferType == DataBuffer.TYPE_SHORT) {
462+ srcScaleFactor[i] = maxNum / 32767.0f;
463+ } else {
464+ srcScaleFactor[i] = maxNum /
465+ ((float) ((1 << srcSM.getSampleSize(i)) - 1));
466+ }
467+ }
468+ for (int i = 0; i < dstNumBands; i++) {
469+ if (dstTransferType == DataBuffer.TYPE_SHORT) {
470+ dstScaleFactor[i] = 32767.0f / maxNum;
471+ } else {
472+ dstScaleFactor[i] =
473+ ((float) ((1 << dstSM.getSampleSize(i)) - 1)) / maxNum;
474+ }
475+ }
476+ int ys = src.getMinY();
477+ int yd = dst.getMinY();
478+ int xs, xd;
479+ int sample;
480+ if (precision == 8) {
481+ byte[] srcLine = new byte[w * srcNumBands];
482+ byte[] dstLine = new byte[w * dstNumBands];
483+ int idx;
484+ // TODO check for src npixels = dst npixels
485+ srcIL = new LCMSImageLayout(
486+ srcLine, srcLine.length/getNumInComponents(),
487+ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
488+ LCMSImageLayout.BYTES_SH(1), getNumInComponents());
489+ dstIL = new LCMSImageLayout(
490+ dstLine, dstLine.length/getNumOutComponents(),
491+ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
492+ LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
493+
494+ // process each scanline
495+ for (int y = 0; y < h; y++, ys++, yd++) {
496+ // get src scanline
497+ xs = src.getMinX();
498+ idx = 0;
499+ for (int x = 0; x < w; x++, xs++) {
500+ for (int i = 0; i < srcNumBands; i++) {
501+ sample = src.getSample(xs, ys, i);
502+ srcLine[idx++] = (byte)
503+ ((sample * srcScaleFactor[i]) + 0.5f);
504+ }
505+ }
506+
507+ // color convert srcLine to dstLine
508+ doTransform(srcIL, dstIL);
509+
510+ // store dst scanline
511+ xd = dst.getMinX();
512+ idx = 0;
513+ for (int x = 0; x < w; x++, xd++) {
514+ for (int i = 0; i < dstNumBands; i++) {
515+ sample = (int) (((dstLine[idx++] & 0xff) *
516+ dstScaleFactor[i]) + 0.5f);
517+ dst.setSample(xd, yd, i, sample);
518+ }
519+ }
520+ }
521+ } else {
522+ short[] srcLine = new short[w * srcNumBands];
523+ short[] dstLine = new short[w * dstNumBands];
524+ int idx;
525+ srcIL = new LCMSImageLayout(
526+ srcLine, srcLine.length/getNumInComponents(),
527+ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
528+ LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
529+
530+ dstIL = new LCMSImageLayout(
531+ dstLine, dstLine.length/getNumOutComponents(),
532+ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
533+ LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
534+
535+ // process each scanline
536+ for (int y = 0; y < h; y++, ys++, yd++) {
537+ // get src scanline
538+ xs = src.getMinX();
539+ idx = 0;
540+ for (int x = 0; x < w; x++, xs++) {
541+ for (int i = 0; i < srcNumBands; i++) {
542+ sample = src.getSample(xs, ys, i);
543+ srcLine[idx++] = (short)
544+ ((sample * srcScaleFactor[i]) + 0.5f);
545+ }
546+ }
547+
548+ // color convert srcLine to dstLine
549+ doTransform(srcIL, dstIL);
550+
551+ // store dst scanline
552+ xd = dst.getMinX();
553+ idx = 0;
554+ for (int x = 0; x < w; x++, xd++) {
555+ for (int i = 0; i < dstNumBands; i++) {
556+ sample = (int) (((dstLine[idx++] & 0xffff) *
557+ dstScaleFactor[i]) + 0.5f);
558+ dst.setSample(xd, yd, i, sample);
559+ }
560+ }
561+ }
562+ }
563+ }
564+
565+ /* convert an array of colors in short format */
566+ /* each color is a contiguous set of array elements */
567+ /* the number of colors is (size of the array) / (number of input/output
568+ components */
569+ public short[] colorConvert(short[] src, short[] dst) {
570+
571+ if (dst == null) {
572+ dst = new short [(src.length/getNumInComponents())*getNumOutComponents()];
573+ }
574+
575+ LCMSImageLayout srcIL = new LCMSImageLayout(
576+ src, src.length/getNumInComponents(),
577+ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
578+ LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
579+
580+ LCMSImageLayout dstIL = new LCMSImageLayout(
581+ dst, dst.length/getNumOutComponents(),
582+ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
583+ LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
584+
585+ doTransform(srcIL, dstIL);
586+
587+ return dst;
588+ }
589+
590+ public byte[] colorConvert(byte[] src, byte[] dst) {
591+ if (dst == null) {
592+ dst = new byte [(src.length/getNumInComponents())*getNumOutComponents()];
593+ }
594+
595+ LCMSImageLayout srcIL = new LCMSImageLayout(
596+ src, src.length/getNumInComponents(),
597+ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
598+ LCMSImageLayout.BYTES_SH(1), getNumInComponents());
599+
600+ LCMSImageLayout dstIL = new LCMSImageLayout(
601+ dst, dst.length/getNumOutComponents(),
602+ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
603+ LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
604+
605+ doTransform(srcIL, dstIL);
606+
607+ return dst;
608+ }
609+}
java/pkg/sun/java2d/cmm/lcms/META-INF/mkfile+6−0
@@ -0,0 +1,6 @@
1+<../../../../../../../mkconfig
2+
3+DIRS=\
4+ services\
5+
6+<$ROOT/mkfiles/mksubdirs
java/pkg/sun/java2d/cmm/lcms/META-INF/services/mkfile+2−0
@@ -0,0 +1,2 @@
1+<../../../../../../../../mkconfig
2+
java/pkg/sun/java2d/cmm/lcms/META-INF/services/sun.java2d.cmm.PCMM+2−0
@@ -0,0 +1,2 @@
1+# Little CMS color management module
2+sun.java2d.cmm.lcms.LCMS
java/pkg/sun/java2d/cmm/lcms/mkfile+14−0
@@ -0,0 +1,14 @@
1+<../../../../../../mkconfig
2+
3+DIRS=\
4+ META-INF\
5+
6+TARG=\
7+ LCMS.dis\
8+ LCMSImageLayout.dis\
9+ LCMSTransform.dis\
10+
11+DISBIN=$ROOT/java/dis/java/java/sun/java2d/cmm/lcms
12+
13+<$ROOT/mkfiles/mkjava
14+<$ROOT/mkfiles/mksubdirs
java/pkg/sun/java2d/cmm/mkfile+17−0
@@ -0,0 +1,17 @@
1+<../../../../../mkconfig
2+
3+DIRS=\
4+ lcms\
5+
6+TARG=\
7+ CMSManager.dis\
8+ ColorTransform.dis\
9+ PCMM.dis\
10+ ProfileActivator.dis\
11+ ProfileDeferralInfo.dis\
12+ ProfileDeferralMgr.dis\
13+
14+DISBIN=$ROOT/java/dis/java/java/sun/java2d/cmm
15+
16+<$ROOT/mkfiles/mkjava
17+<$ROOT/mkfiles/mksubdirs
java/pkg/sun/java2d/loops/Blit$AnyBlit.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/Blit$GeneralMaskBlit.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/Blit$GeneralXorBlit.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/Blit$TraceBlit.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/Blit.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/Blit.java+332−0
@@ -0,0 +1,332 @@
1+/*
2+ * Copyright (c) 1999, 2004, 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+
26+package sun.java2d.loops;
27+
28+import java.awt.Composite;
29+import java.awt.CompositeContext;
30+import java.awt.RenderingHints;
31+import java.awt.image.ColorModel;
32+import java.awt.image.Raster;
33+import java.awt.image.WritableRaster;
34+import java.lang.ref.WeakReference;
35+import sun.java2d.loops.GraphicsPrimitive;
36+import sun.java2d.SurfaceData;
37+import sun.java2d.pipe.Region;
38+import sun.java2d.pipe.SpanIterator;
39+
40+/**
41+ * Blit
42+ * 1) copies rectangle of pixels from one surface to another
43+ * 2) performs compositing of colors based upon a Composite
44+ * parameter
45+ *
46+ * precise behavior is undefined if the source surface
47+ * and the destination surface are the same surface
48+ * with overlapping regions of pixels
49+ */
50+
51+public class Blit extends GraphicsPrimitive
52+{
53+ public static final String methodSignature = "Blit(...)".toString();
54+
55+ public static final int primTypeID = makePrimTypeID();
56+
57+ private static RenderCache blitcache = new RenderCache(20);
58+
59+ public static Blit locate(SurfaceType srctype,
60+ CompositeType comptype,
61+ SurfaceType dsttype)
62+ {
63+ return (Blit)
64+ GraphicsPrimitiveMgr.locate(primTypeID,
65+ srctype, comptype, dsttype);
66+ }
67+
68+ public static Blit getFromCache(SurfaceType src,
69+ CompositeType comp,
70+ SurfaceType dst)
71+ {
72+ Object o = blitcache.get(src, comp, dst);
73+ if (o != null) {
74+ return (Blit) o;
75+ }
76+
77+ Blit blit = locate(src, comp, dst);
78+ if (blit == null) {
79+ System.out.println("blit loop not found for:");
80+ System.out.println("src: "+src);
81+ System.out.println("comp: "+comp);
82+ System.out.println("dst: "+dst);
83+ } else {
84+ blitcache.put(src, comp, dst, blit);
85+ }
86+ return blit;
87+ }
88+
89+ protected Blit(SurfaceType srctype,
90+ CompositeType comptype,
91+ SurfaceType dsttype)
92+ {
93+ super(methodSignature, primTypeID, srctype, comptype, dsttype);
94+ }
95+
96+ public Blit(long pNativePrim,
97+ SurfaceType srctype,
98+ CompositeType comptype,
99+ SurfaceType dsttype)
100+ {
101+ super(pNativePrim, methodSignature, primTypeID, srctype, comptype, dsttype);
102+ }
103+
104+ /**
105+ * All Blit implementors must have this invoker method
106+ */
107+ public native void Blit(SurfaceData src, SurfaceData dst,
108+ Composite comp, Region clip,
109+ int srcx, int srcy,
110+ int dstx, int dsty,
111+ int width, int height);
112+
113+ static {
114+ GraphicsPrimitiveMgr.registerGeneral(new Blit(null, null, null));
115+ }
116+
117+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
118+ CompositeType comptype,
119+ SurfaceType dsttype)
120+ {
121+ /*
122+ System.out.println("Constructing general blit for:");
123+ System.out.println("src: "+srctype);
124+ System.out.println("comp: "+comptype);
125+ System.out.println("dst: "+dsttype);
126+ */
127+
128+ if (comptype.isDerivedFrom(CompositeType.Xor)) {
129+ GeneralXorBlit gxb = new GeneralXorBlit(srctype,
130+ comptype,
131+ dsttype);
132+ setupGeneralBinaryOp(gxb);
133+ return gxb;
134+ } else if (comptype.isDerivedFrom(CompositeType.AnyAlpha)) {
135+ return new GeneralMaskBlit(srctype, comptype, dsttype);
136+ } else {
137+ return AnyBlit.instance;
138+ }
139+ }
140+
141+ private static class AnyBlit extends Blit {
142+ public static AnyBlit instance = new AnyBlit();
143+
144+ public AnyBlit() {
145+ super(SurfaceType.Any, CompositeType.Any, SurfaceType.Any);
146+ }
147+
148+ public void Blit(SurfaceData srcData,
149+ SurfaceData dstData,
150+ Composite comp,
151+ Region clip,
152+ int srcx, int srcy,
153+ int dstx, int dsty,
154+ int width, int height)
155+ {
156+ ColorModel srcCM = srcData.getColorModel();
157+ ColorModel dstCM = dstData.getColorModel();
158+ // REMIND: Should get RenderingHints from sg2d
159+ CompositeContext ctx = comp.createContext(srcCM, dstCM,
160+ new RenderingHints(null));
161+ Raster srcRas = srcData.getRaster(srcx, srcy, width, height);
162+ WritableRaster dstRas =
163+ (WritableRaster) dstData.getRaster(dstx, dsty, width, height);
164+
165+ if (clip == null) {
166+ clip = Region.getInstanceXYWH(dstx, dsty, width, height);
167+ }
168+ int span[] = {dstx, dsty, dstx+width, dsty+height};
169+ SpanIterator si = clip.getSpanIterator(span);
170+ srcx -= dstx;
171+ srcy -= dsty;
172+ while (si.nextSpan(span)) {
173+ int w = span[2] - span[0];
174+ int h = span[3] - span[1];
175+ srcRas = srcRas.createChild(srcx + span[0], srcy + span[1],
176+ w, h, 0, 0, null);
177+ dstRas = dstRas.createWritableChild(span[0], span[1],
178+ w, h, 0, 0, null);
179+ ctx.compose(srcRas, dstRas, dstRas);
180+ }
181+ ctx.dispose();
182+ }
183+ }
184+
185+ private static class GeneralMaskBlit extends Blit {
186+ MaskBlit performop;
187+
188+ public GeneralMaskBlit(SurfaceType srctype,
189+ CompositeType comptype,
190+ SurfaceType dsttype)
191+ {
192+ super(srctype, comptype, dsttype);
193+ performop = MaskBlit.locate(srctype, comptype, dsttype);
194+ }
195+
196+ public void Blit(SurfaceData srcData,
197+ SurfaceData dstData,
198+ Composite comp,
199+ Region clip,
200+ int srcx, int srcy,
201+ int dstx, int dsty,
202+ int width, int height)
203+ {
204+ performop.MaskBlit(srcData, dstData, comp, clip,
205+ srcx, srcy, dstx, dsty,
206+ width, height,
207+ null, 0, 0);
208+ }
209+ }
210+
211+ private static class GeneralXorBlit
212+ extends Blit
213+ implements GeneralBinaryOp
214+ {
215+ Blit convertsrc;
216+ Blit convertdst;
217+ Blit performop;
218+ Blit convertresult;
219+
220+ WeakReference srcTmp;
221+ WeakReference dstTmp;
222+
223+ public GeneralXorBlit(SurfaceType srctype,
224+ CompositeType comptype,
225+ SurfaceType dsttype)
226+ {
227+ super(srctype, comptype, dsttype);
228+ }
229+
230+ public void setPrimitives(Blit srcconverter,
231+ Blit dstconverter,
232+ GraphicsPrimitive genericop,
233+ Blit resconverter)
234+ {
235+ this.convertsrc = srcconverter;
236+ this.convertdst = dstconverter;
237+ this.performop = (Blit) genericop;
238+ this.convertresult = resconverter;
239+ }
240+
241+ public synchronized void Blit(SurfaceData srcData,
242+ SurfaceData dstData,
243+ Composite comp,
244+ Region clip,
245+ int srcx, int srcy,
246+ int dstx, int dsty,
247+ int width, int height)
248+ {
249+ SurfaceData src, dst;
250+ Region opclip;
251+ int sx, sy, dx, dy;
252+
253+ if (convertsrc == null) {
254+ src = srcData;
255+ sx = srcx;
256+ sy = srcy;
257+ } else {
258+ SurfaceData cachedSrc = null;
259+ if (srcTmp != null) {
260+ cachedSrc = (SurfaceData) srcTmp.get();
261+ }
262+ src = convertFrom(convertsrc, srcData, srcx, srcy,
263+ width, height, cachedSrc);
264+ sx = 0;
265+ sy = 0;
266+ if (src != cachedSrc) {
267+ srcTmp = new WeakReference(src);
268+ }
269+ }
270+
271+ if (convertdst == null) {
272+ dst = dstData;
273+ dx = dstx;
274+ dy = dsty;
275+ opclip = clip;
276+ } else {
277+ // assert: convertresult != null
278+ SurfaceData cachedDst = null;
279+ if (dstTmp != null) {
280+ cachedDst = (SurfaceData) dstTmp.get();
281+ }
282+ dst = convertFrom(convertdst, dstData, dstx, dsty,
283+ width, height, cachedDst);
284+ dx = 0;
285+ dy = 0;
286+ opclip = null;
287+ if (dst != cachedDst) {
288+ dstTmp = new WeakReference(dst);
289+ }
290+ }
291+
292+ performop.Blit(src, dst, comp, opclip,
293+ sx, sy, dx, dy,
294+ width, height);
295+
296+ if (convertresult != null) {
297+ // assert: convertdst != null
298+ convertTo(convertresult, dst, dstData, clip,
299+ dstx, dsty, width, height);
300+ }
301+ }
302+ }
303+
304+ public GraphicsPrimitive traceWrap() {
305+ return new TraceBlit(this);
306+ }
307+
308+ private static class TraceBlit extends Blit {
309+ Blit target;
310+
311+ public TraceBlit(Blit target) {
312+ super(target.getSourceType(),
313+ target.getCompositeType(),
314+ target.getDestType());
315+ this.target = target;
316+ }
317+
318+ public GraphicsPrimitive traceWrap() {
319+ return this;
320+ }
321+
322+ public void Blit(SurfaceData src, SurfaceData dst,
323+ Composite comp, Region clip,
324+ int srcx, int srcy, int dstx, int dsty,
325+ int width, int height)
326+ {
327+ tracePrimitive(target);
328+ target.Blit(src, dst, comp, clip,
329+ srcx, srcy, dstx, dsty, width, height);
330+ }
331+ }
332+}
java/pkg/sun/java2d/loops/BlitBg$General.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/BlitBg$TraceBlitBg.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/BlitBg.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/BlitBg.java+217−0
@@ -0,0 +1,217 @@
1+/*
2+ * Copyright (c) 1999, 2008, 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+
26+package sun.java2d.loops;
27+
28+import java.awt.Font;
29+import java.awt.Color;
30+import java.awt.Composite;
31+import java.awt.AlphaComposite;
32+import java.awt.Transparency;
33+import java.awt.image.ColorModel;
34+import java.awt.image.WritableRaster;
35+import java.awt.image.BufferedImage;
36+import sun.awt.image.BufImgSurfaceData;
37+import sun.java2d.loops.GraphicsPrimitive;
38+import sun.java2d.SurfaceData;
39+import sun.java2d.SunGraphics2D;
40+import sun.java2d.pipe.Region;
41+
42+/**
43+ * BlitBg
44+ * 1) copies rectangle of pixels from one surface to another
45+ * 2) performs compositing of colors based upon a Composite
46+ * parameter
47+ * 3) assumes that non-opaque pixels are to be blended with
48+ * the indicated Bg color before compositing with the
49+ * destination
50+ *
51+ * precise behavior is undefined if the source surface
52+ * and the destination surface are the same surface
53+ * with overlapping regions of pixels
54+ */
55+public class BlitBg extends GraphicsPrimitive
56+{
57+ public static final String methodSignature = "BlitBg(...)".toString();
58+
59+ public static final int primTypeID = makePrimTypeID();
60+
61+ private static RenderCache blitcache = new RenderCache(20);
62+
63+ public static BlitBg locate(SurfaceType srctype,
64+ CompositeType comptype,
65+ SurfaceType dsttype)
66+ {
67+ return (BlitBg)
68+ GraphicsPrimitiveMgr.locate(primTypeID,
69+ srctype, comptype, dsttype);
70+ }
71+
72+ public static BlitBg getFromCache(SurfaceType src,
73+ CompositeType comp,
74+ SurfaceType dst)
75+ {
76+ Object o = blitcache.get(src, comp, dst);
77+ if (o != null) {
78+ return (BlitBg) o;
79+ }
80+ BlitBg blit = locate(src, comp, dst);
81+ if (blit == null) {
82+ System.out.println("blitbg loop not found for:");
83+ System.out.println("src: "+src);
84+ System.out.println("comp: "+comp);
85+ System.out.println("dst: "+dst);
86+ } else {
87+ blitcache.put(src, comp, dst, blit);
88+ }
89+ return blit;
90+ }
91+
92+ protected BlitBg(SurfaceType srctype,
93+ CompositeType comptype,
94+ SurfaceType dsttype)
95+ {
96+ super(methodSignature, primTypeID, srctype, comptype, dsttype);
97+ }
98+
99+ public BlitBg(long pNativePrim,
100+ SurfaceType srctype,
101+ CompositeType comptype,
102+ SurfaceType dsttype)
103+ {
104+ super(pNativePrim, methodSignature, primTypeID, srctype, comptype, dsttype);
105+ }
106+
107+ /**
108+ * All BlitBg implementors must have this invoker method
109+ */
110+ public native void BlitBg(SurfaceData src, SurfaceData dst,
111+ Composite comp, Region clip,
112+ int bgColor,
113+ int srcx, int srcy,
114+ int dstx, int dsty,
115+ int width, int height);
116+
117+ static {
118+ GraphicsPrimitiveMgr.registerGeneral(new BlitBg(null, null, null));
119+ }
120+
121+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
122+ CompositeType comptype,
123+ SurfaceType dsttype)
124+ {
125+ /*
126+ System.out.println("Constructing general blitbg for:");
127+ System.out.println("src: "+srctype);
128+ System.out.println("comp: "+comptype);
129+ System.out.println("dst: "+dsttype);
130+ */
131+ return new General(srctype, comptype, dsttype);
132+ }
133+
134+ private static class General extends BlitBg {
135+ CompositeType compositeType;
136+
137+ public General(SurfaceType srctype,
138+ CompositeType comptype,
139+ SurfaceType dsttype)
140+ {
141+ super(srctype, comptype, dsttype);
142+ compositeType = comptype;
143+ }
144+
145+ @Override
146+ public void BlitBg(SurfaceData srcData,
147+ SurfaceData dstData,
148+ Composite comp,
149+ Region clip,
150+ int bgArgb,
151+ int srcx, int srcy,
152+ int dstx, int dsty,
153+ int width, int height)
154+ {
155+ ColorModel dstModel = dstData.getColorModel();
156+ boolean bgHasAlpha = (bgArgb >>> 24) != 0xff;
157+ if (!dstModel.hasAlpha() && bgHasAlpha) {
158+ dstModel = ColorModel.getRGBdefault();
159+ }
160+ WritableRaster wr =
161+ dstModel.createCompatibleWritableRaster(width, height);
162+ boolean isPremult = dstModel.isAlphaPremultiplied();
163+ BufferedImage bimg =
164+ new BufferedImage(dstModel, wr, isPremult, null);
165+ SurfaceData tmpData = BufImgSurfaceData.createData(bimg);
166+ Color bgColor = new Color(bgArgb, bgHasAlpha);
167+ SunGraphics2D sg2d = new SunGraphics2D(tmpData, bgColor, bgColor,
168+ defaultFont);
169+ FillRect fillop = FillRect.locate(SurfaceType.AnyColor,
170+ CompositeType.SrcNoEa,
171+ tmpData.getSurfaceType());
172+ Blit combineop = Blit.getFromCache(srcData.getSurfaceType(),
173+ CompositeType.SrcOverNoEa,
174+ tmpData.getSurfaceType());
175+ Blit blitop = Blit.getFromCache(tmpData.getSurfaceType(), compositeType,
176+ dstData.getSurfaceType());
177+ fillop.FillRect(sg2d, tmpData, 0, 0, width, height);
178+ combineop.Blit(srcData, tmpData, AlphaComposite.SrcOver, null,
179+ srcx, srcy, 0, 0, width, height);
180+ blitop.Blit(tmpData, dstData, comp, clip,
181+ 0, 0, dstx, dsty, width, height);
182+ }
183+
184+ private static Font defaultFont = new Font("Dialog", Font.PLAIN, 12);
185+ }
186+
187+ public GraphicsPrimitive traceWrap() {
188+ return new TraceBlitBg(this);
189+ }
190+
191+ private static class TraceBlitBg extends BlitBg {
192+ BlitBg target;
193+
194+ public TraceBlitBg(BlitBg target) {
195+ super(target.getSourceType(),
196+ target.getCompositeType(),
197+ target.getDestType());
198+ this.target = target;
199+ }
200+
201+ public GraphicsPrimitive traceWrap() {
202+ return this;
203+ }
204+
205+ @Override
206+ public void BlitBg(SurfaceData src, SurfaceData dst,
207+ Composite comp, Region clip,
208+ int bgColor,
209+ int srcx, int srcy, int dstx, int dsty,
210+ int width, int height)
211+ {
212+ tracePrimitive(target);
213+ target.BlitBg(src, dst, comp, clip, bgColor,
214+ srcx, srcy, dstx, dsty, width, height);
215+ }
216+ }
217+}
java/pkg/sun/java2d/loops/CompositeType.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/CompositeType.java+295−0
@@ -0,0 +1,295 @@
1+/*
2+ * Copyright (c) 1999, 2010, 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+
26+package sun.java2d.loops;
27+
28+import java.awt.image.BufferedImage;
29+import java.awt.AlphaComposite;
30+import java.util.HashMap;
31+
32+/**
33+ * A CompositeType object provides a chained description of a type of
34+ * algorithm for color compositing. The object will provide a single
35+ * String constant descriptor which is one way of describing a particular
36+ * compositing algorithm as well as a pointer to another CompositeType
37+ * which describes a more general algorithm for achieving the same result.
38+ * <p>
39+ * A description of a more specific algorithm is considered a "subtype"
40+ * and a description of a more general algorithm is considered a "supertype".
41+ * Thus, the deriveSubType method provides a way to create a new CompositeType
42+ * that is related to but more specific than an existing CompositeType and
43+ * the getSuperType method provides a way to ask a given CompositeType
44+ * for a more general algorithm to achieve the same result.
45+ * <p>
46+ * Note that you cannot construct a brand new root for a chain since
47+ * the constructor is private. Every chain of types must at some point
48+ * derive from the Any node provided here using the deriveSubType()
49+ * method. The presence of this common Any node on every chain
50+ * ensures that all chains end with the DESC_ANY descriptor so that
51+ * a suitable General GraphicsPrimitive object can be obtained for
52+ * the indicated algorithm if all of the more specific searches fail.
53+ */
54+public final class CompositeType {
55+
56+ private static int unusedUID = 1;
57+ private static final HashMap<String,Integer> compositeUIDMap =
58+ new HashMap<String,Integer>(100);
59+
60+ /*
61+ * CONSTANTS USED BY ALL PRIMITIVES TO DESCRIBE THE COMPOSITING
62+ * ALGORITHMS THEY CAN PERFORM
63+ */
64+
65+ /**
66+ * algorithm is a general algorithm that uses a CompositeContext
67+ * to do the rendering.
68+ */
69+ public static final String DESC_ANY = "Any CompositeContext";
70+
71+ /**
72+ * constant used to describe the Graphics.setXORMode() algorithm
73+ */
74+ public static final String DESC_XOR = "XOR mode";
75+
76+ /**
77+ * constants used to describe the various AlphaComposite
78+ * algorithms.
79+ */
80+ public static final String DESC_CLEAR = "Porter-Duff Clear";
81+ public static final String DESC_SRC = "Porter-Duff Src";
82+ public static final String DESC_DST = "Porter-Duff Dst";
83+ public static final String DESC_SRC_OVER = "Porter-Duff Src Over Dst";
84+ public static final String DESC_DST_OVER = "Porter-Duff Dst Over Src";
85+ public static final String DESC_SRC_IN = "Porter-Duff Src In Dst";
86+ public static final String DESC_DST_IN = "Porter-Duff Dst In Src";
87+ public static final String DESC_SRC_OUT = "Porter-Duff Src HeldOutBy Dst";
88+ public static final String DESC_DST_OUT = "Porter-Duff Dst HeldOutBy Src";
89+ public static final String DESC_SRC_ATOP = "Porter-Duff Src Atop Dst";
90+ public static final String DESC_DST_ATOP = "Porter-Duff Dst Atop Src";
91+ public static final String DESC_ALPHA_XOR = "Porter-Duff Xor";
92+
93+ /**
94+ * constants used to describe the two common cases of
95+ * AlphaComposite algorithms that are simpler if there
96+ * is not extraAlpha.
97+ */
98+ public static final String
99+ DESC_SRC_NO_EA = "Porter-Duff Src, No Extra Alpha";
100+ public static final String
101+ DESC_SRC_OVER_NO_EA = "Porter-Duff SrcOverDst, No Extra Alpha";
102+
103+ /**
104+ * constant used to describe an algorithm that implements all 8 of
105+ * the Porter-Duff rules in one Primitive.
106+ */
107+ public static final String DESC_ANY_ALPHA = "Any AlphaComposite Rule";
108+
109+ /*
110+ * END OF COMPOSITE ALGORITHM TYPE CONSTANTS
111+ */
112+
113+ /**
114+ * The root CompositeType object for all chains of algorithm descriptions.
115+ */
116+ public static final CompositeType
117+ Any = new CompositeType(null, DESC_ANY);
118+
119+ /*
120+ * START OF CompositeeType OBJECTS FOR THE VARIOUS CONSTANTS
121+ */
122+
123+ public static final CompositeType
124+ General = Any;
125+
126+ public static final CompositeType
127+ AnyAlpha = General.deriveSubType(DESC_ANY_ALPHA);
128+ public static final CompositeType
129+ Xor = General.deriveSubType(DESC_XOR);
130+
131+ public static final CompositeType
132+ Clear = AnyAlpha.deriveSubType(DESC_CLEAR);
133+ public static final CompositeType
134+ Src = AnyAlpha.deriveSubType(DESC_SRC);
135+ public static final CompositeType
136+ Dst = AnyAlpha.deriveSubType(DESC_DST);
137+ public static final CompositeType
138+ SrcOver = AnyAlpha.deriveSubType(DESC_SRC_OVER);
139+ public static final CompositeType
140+ DstOver = AnyAlpha.deriveSubType(DESC_DST_OVER);
141+ public static final CompositeType
142+ SrcIn = AnyAlpha.deriveSubType(DESC_SRC_IN);
143+ public static final CompositeType
144+ DstIn = AnyAlpha.deriveSubType(DESC_DST_IN);
145+ public static final CompositeType
146+ SrcOut = AnyAlpha.deriveSubType(DESC_SRC_OUT);
147+ public static final CompositeType
148+ DstOut = AnyAlpha.deriveSubType(DESC_DST_OUT);
149+ public static final CompositeType
150+ SrcAtop = AnyAlpha.deriveSubType(DESC_SRC_ATOP);
151+ public static final CompositeType
152+ DstAtop = AnyAlpha.deriveSubType(DESC_DST_ATOP);
153+ public static final CompositeType
154+ AlphaXor = AnyAlpha.deriveSubType(DESC_ALPHA_XOR);
155+
156+ public static final CompositeType
157+ SrcNoEa = Src.deriveSubType(DESC_SRC_NO_EA);
158+ public static final CompositeType
159+ SrcOverNoEa = SrcOver.deriveSubType(DESC_SRC_OVER_NO_EA);
160+
161+ /*
162+ * A special CompositeType for the case where we are filling in
163+ * SrcOverNoEa mode with an opaque color. In that case then the
164+ * best loop for us to use would be a SrcNoEa loop, but what if
165+ * there is no such loop? In that case then we would end up
166+ * backing off to a Src loop (which should still be fine) or an
167+ * AnyAlpha loop which would be slower than a SrcOver loop in
168+ * most cases.
169+ * The fix is to use the following chain which looks for loops
170+ * in the following order:
171+ * SrcNoEa, Src, SrcOverNoEa, SrcOver, AnyAlpha
172+ */
173+ public static final CompositeType
174+ OpaqueSrcOverNoEa = SrcOverNoEa.deriveSubType(DESC_SRC)
175+ .deriveSubType(DESC_SRC_NO_EA);
176+
177+ /*
178+ * END OF CompositeType OBJECTS FOR THE VARIOUS CONSTANTS
179+ */
180+
181+ /**
182+ * Return a new CompositeType object which uses this object as its
183+ * more general "supertype" descriptor. If no operation can be
184+ * found that implements the algorithm described more exactly
185+ * by desc, then this object will define the more general
186+ * compositing algorithm that can be used instead.
187+ */
188+ public CompositeType deriveSubType(String desc) {
189+ return new CompositeType(this, desc);
190+ }
191+
192+ /**
193+ * Return a CompositeType object for the specified AlphaComposite
194+ * rule.
195+ */
196+ public static CompositeType forAlphaComposite(AlphaComposite ac) {
197+ switch (ac.getRule()) {
198+ case AlphaComposite.CLEAR:
199+ return Clear;
200+ case AlphaComposite.SRC:
201+ if (ac.getAlpha() >= 1.0f) {
202+ return SrcNoEa;
203+ } else {
204+ return Src;
205+ }
206+ case AlphaComposite.DST:
207+ return Dst;
208+ case AlphaComposite.SRC_OVER:
209+ if (ac.getAlpha() >= 1.0f) {
210+ return SrcOverNoEa;
211+ } else {
212+ return SrcOver;
213+ }
214+ case AlphaComposite.DST_OVER:
215+ return DstOver;
216+ case AlphaComposite.SRC_IN:
217+ return SrcIn;
218+ case AlphaComposite.DST_IN:
219+ return DstIn;
220+ case AlphaComposite.SRC_OUT:
221+ return SrcOut;
222+ case AlphaComposite.DST_OUT:
223+ return DstOut;
224+ case AlphaComposite.SRC_ATOP:
225+ return SrcAtop;
226+ case AlphaComposite.DST_ATOP:
227+ return DstAtop;
228+ case AlphaComposite.XOR:
229+ return AlphaXor;
230+ default:
231+ throw new InternalError("Unrecognized alpha rule");
232+ }
233+ }
234+
235+ private int uniqueID;
236+ private String desc;
237+ private CompositeType next;
238+
239+ private CompositeType(CompositeType parent, String desc) {
240+ next = parent;
241+ this.desc = desc;
242+ this.uniqueID = makeUniqueID(desc);
243+ }
244+
245+ public synchronized static final int makeUniqueID(String desc) {
246+ Integer i = compositeUIDMap.get(desc);
247+
248+ if (i == null) {
249+ if (unusedUID > 255) {
250+ throw new InternalError("composite type id overflow");
251+ }
252+ i = unusedUID++;
253+ compositeUIDMap.put(desc, i);
254+ }
255+ return i;
256+ }
257+
258+ public int getUniqueID() {
259+ return uniqueID;
260+ }
261+
262+ public String getDescriptor() {
263+ return desc;
264+ }
265+
266+ public CompositeType getSuperType() {
267+ return next;
268+ }
269+
270+ public int hashCode() {
271+ return desc.hashCode();
272+ }
273+
274+ public boolean isDerivedFrom(CompositeType other) {
275+ CompositeType comptype = this;
276+ do {
277+ if (comptype.desc == other.desc) {
278+ return true;
279+ }
280+ comptype = comptype.next;
281+ } while (comptype != null);
282+ return false;
283+ }
284+
285+ public boolean equals(Object o) {
286+ if (o instanceof CompositeType) {
287+ return (((CompositeType) o).uniqueID == this.uniqueID);
288+ }
289+ return false;
290+ }
291+
292+ public String toString() {
293+ return desc;
294+ }
295+}
java/pkg/sun/java2d/loops/CustomComponent.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/CustomComponent.java+329−0
@@ -0,0 +1,329 @@
1+/*
2+ * Copyright (c) 1997, 2007, 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+
26+/*
27+ * @author Charlton Innovations, Inc.
28+ * @author Jim Graham
29+ */
30+
31+package sun.java2d.loops;
32+
33+import java.awt.Composite;
34+import java.awt.Rectangle;
35+import java.awt.image.ColorModel;
36+import java.awt.image.DataBuffer;
37+import java.awt.image.Raster;
38+import java.awt.image.WritableRaster;
39+import sun.awt.image.IntegerComponentRaster;
40+import sun.java2d.SurfaceData;
41+import sun.java2d.pipe.Region;
42+import sun.java2d.pipe.SpanIterator;
43+
44+/**
45+ * CustomComponent, collection of GraphicsPrimitive
46+ * Basically, this collection of components performs conversion from
47+ * ANY to ANY via opaque copy
48+ */
49+public final class CustomComponent {
50+ public static void register() {
51+ // REMIND: This does not work for all destinations yet since
52+ // the screen SurfaceData objects do not implement getRaster
53+ Class owner = CustomComponent.class;
54+ GraphicsPrimitive[] primitives = {
55+ new GraphicsPrimitiveProxy(owner, "OpaqueCopyAnyToArgb",
56+ Blit.methodSignature,
57+ Blit.primTypeID,
58+ SurfaceType.Any,
59+ CompositeType.SrcNoEa,
60+ SurfaceType.IntArgb),
61+ new GraphicsPrimitiveProxy(owner, "OpaqueCopyArgbToAny",
62+ Blit.methodSignature,
63+ Blit.primTypeID,
64+ SurfaceType.IntArgb,
65+ CompositeType.SrcNoEa,
66+ SurfaceType.Any),
67+ new GraphicsPrimitiveProxy(owner, "XorCopyArgbToAny",
68+ Blit.methodSignature,
69+ Blit.primTypeID,
70+ SurfaceType.IntArgb,
71+ CompositeType.Xor,
72+ SurfaceType.Any),
73+ };
74+ GraphicsPrimitiveMgr.register(primitives);
75+ }
76+
77+ public static Region getRegionOfInterest(SurfaceData src, SurfaceData dst,
78+ Region clip,
79+ int srcx, int srcy,
80+ int dstx, int dsty,
81+ int w, int h)
82+ {
83+ /*
84+ * Intersect all of:
85+ * - operation area (dstx, dsty, w, h)
86+ * - destination bounds
87+ * - (translated) src bounds
88+ * - supplied clip (may be non-rectangular)
89+ * Intersect the rectangular regions first since those are
90+ * simpler operations.
91+ */
92+ Region ret = Region.getInstanceXYWH(dstx, dsty, w, h);
93+ ret = ret.getIntersection(dst.getBounds());
94+ Rectangle r = src.getBounds();
95+ // srcxy in src space maps to dstxy in dst space
96+ r.translate(dstx - srcx, dsty - srcy);
97+ ret = ret.getIntersection(r);
98+ if (clip != null) {
99+ // Intersect with clip last since it may be non-rectangular
100+ ret = ret.getIntersection(clip);
101+ }
102+ return ret;
103+ }
104+}
105+
106+/**
107+ * ANY format to ARGB format Blit
108+ */
109+class OpaqueCopyAnyToArgb extends Blit {
110+ OpaqueCopyAnyToArgb() {
111+ super(SurfaceType.Any,
112+ CompositeType.SrcNoEa,
113+ SurfaceType.IntArgb);
114+ }
115+
116+ public void Blit(SurfaceData src, SurfaceData dst,
117+ Composite comp, Region clip,
118+ int srcx, int srcy, int dstx, int dsty, int w, int h)
119+ {
120+ Raster srcRast = src.getRaster(srcx, srcy, w, h);
121+ ColorModel srcCM = src.getColorModel();
122+
123+ Raster dstRast = dst.getRaster(dstx, dsty, w, h);
124+ IntegerComponentRaster icr = (IntegerComponentRaster) dstRast;
125+ int[] dstPix = icr.getDataStorage();
126+
127+ Region roi = CustomComponent.getRegionOfInterest(src, dst, clip,
128+ srcx, srcy,
129+ dstx, dsty, w, h);
130+ SpanIterator si = roi.getSpanIterator();
131+
132+ Object srcPix = null;
133+
134+ int dstScan = icr.getScanlineStride();
135+ // assert(icr.getPixelStride() == 1);
136+ srcx -= dstx;
137+ srcy -= dsty;
138+ int span[] = new int[4];
139+ while (si.nextSpan(span)) {
140+ int rowoff = icr.getDataOffset(0) + span[1] * dstScan + span[0];
141+ for (int y = span[1]; y < span[3]; y++) {
142+ int off = rowoff;
143+ for (int x = span[0]; x < span[2]; x++) {
144+ srcPix = srcRast.getDataElements(x+srcx, y+srcy, srcPix);
145+ dstPix[off++] = srcCM.getRGB(srcPix);
146+ }
147+ rowoff += dstScan;
148+ }
149+ }
150+ // Pixels in the dest were modified directly, we must
151+ // manually notify the raster that it was modified
152+ icr.markDirty();
153+ // REMIND: We need to do something to make sure that dstRast
154+ // is put back to the destination (as in the native Release
155+ // function)
156+ // src.releaseRaster(srcRast); // NOP?
157+ // dst.releaseRaster(dstRast);
158+ }
159+}
160+
161+/**
162+ * ARGB format to ANY format Blit
163+ */
164+class OpaqueCopyArgbToAny extends Blit {
165+ OpaqueCopyArgbToAny() {
166+ super(SurfaceType.IntArgb,
167+ CompositeType.SrcNoEa,
168+ SurfaceType.Any);
169+ }
170+
171+ public void Blit(SurfaceData src, SurfaceData dst,
172+ Composite comp, Region clip,
173+ int srcx, int srcy, int dstx, int dsty, int w, int h)
174+ {
175+ Raster srcRast = src.getRaster(srcx, srcy, w, h);
176+ IntegerComponentRaster icr = (IntegerComponentRaster) srcRast;
177+ int[] srcPix = icr.getDataStorage();
178+
179+ WritableRaster dstRast =
180+ (WritableRaster) dst.getRaster(dstx, dsty, w, h);
181+ ColorModel dstCM = dst.getColorModel();
182+
183+ Region roi = CustomComponent.getRegionOfInterest(src, dst, clip,
184+ srcx, srcy,
185+ dstx, dsty, w, h);
186+ SpanIterator si = roi.getSpanIterator();
187+
188+ Object dstPix = null;
189+
190+ int srcScan = icr.getScanlineStride();
191+ // assert(icr.getPixelStride() == 1);
192+ srcx -= dstx;
193+ srcy -= dsty;
194+ int span[] = new int[4];
195+ while (si.nextSpan(span)) {
196+ int rowoff = (icr.getDataOffset(0) +
197+ (srcy + span[1]) * srcScan +
198+ (srcx + span[0]));
199+ for (int y = span[1]; y < span[3]; y++) {
200+ int off = rowoff;
201+ for (int x = span[0]; x < span[2]; x++) {
202+ dstPix = dstCM.getDataElements(srcPix[off++], dstPix);
203+ dstRast.setDataElements(x, y, dstPix);
204+ }
205+ rowoff += srcScan;
206+ }
207+ }
208+ // REMIND: We need to do something to make sure that dstRast
209+ // is put back to the destination (as in the native Release
210+ // function)
211+ // src.releaseRaster(srcRast); // NOP?
212+ // dst.releaseRaster(dstRast);
213+ }
214+}
215+
216+/**
217+ * ARGB format to ANY format Blit (pixels are XORed together with XOR pixel)
218+ */
219+class XorCopyArgbToAny extends Blit {
220+ XorCopyArgbToAny() {
221+ super(SurfaceType.IntArgb,
222+ CompositeType.Xor,
223+ SurfaceType.Any);
224+ }
225+
226+ public void Blit(SurfaceData src, SurfaceData dst,
227+ Composite comp, Region clip,
228+ int srcx, int srcy, int dstx, int dsty, int w, int h)
229+ {
230+ Raster srcRast = src.getRaster(srcx, srcy, w, h);
231+ IntegerComponentRaster icr = (IntegerComponentRaster) srcRast;
232+ int[] srcPix = icr.getDataStorage();
233+
234+ WritableRaster dstRast =
235+ (WritableRaster) dst.getRaster(dstx, dsty, w, h);
236+ ColorModel dstCM = dst.getColorModel();
237+
238+ Region roi = CustomComponent.getRegionOfInterest(src, dst, clip,
239+ srcx, srcy,
240+ dstx, dsty, w, h);
241+ SpanIterator si = roi.getSpanIterator();
242+
243+ int xorrgb = ((XORComposite)comp).getXorColor().getRGB();
244+ Object xorPixel = dstCM.getDataElements(xorrgb, null);
245+
246+ Object srcPixel = null;
247+ Object dstPixel = null;
248+
249+ int srcScan = icr.getScanlineStride();
250+ // assert(icr.getPixelStride() == 1);
251+ srcx -= dstx;
252+ srcy -= dsty;
253+ int span[] = new int[4];
254+ while (si.nextSpan(span)) {
255+ int rowoff = (icr.getDataOffset(0) +
256+ (srcy + span[1]) * srcScan +
257+ (srcx + span[0]));
258+ for (int y = span[1]; y < span[3]; y++) {
259+ int off = rowoff;
260+ for (int x = span[0]; x < span[2]; x++) {
261+ // REMIND: alpha bits of the destination pixel are
262+ // currently altered by the XOR operation, but
263+ // should be left untouched
264+ srcPixel = dstCM.getDataElements(srcPix[off++], srcPixel);
265+ dstPixel = dstRast.getDataElements(x, y, dstPixel);
266+
267+ switch (dstCM.getTransferType()) {
268+ case DataBuffer.TYPE_BYTE:
269+ byte[] bytesrcarr = (byte[]) srcPixel;
270+ byte[] bytedstarr = (byte[]) dstPixel;
271+ byte[] bytexorarr = (byte[]) xorPixel;
272+ for (int i = 0; i < bytedstarr.length; i++) {
273+ bytedstarr[i] ^= bytesrcarr[i] ^ bytexorarr[i];
274+ }
275+ break;
276+ case DataBuffer.TYPE_SHORT:
277+ case DataBuffer.TYPE_USHORT:
278+ short[] shortsrcarr = (short[]) srcPixel;
279+ short[] shortdstarr = (short[]) dstPixel;
280+ short[] shortxorarr = (short[]) xorPixel;
281+ for (int i = 0; i < shortdstarr.length; i++) {
282+ shortdstarr[i] ^= shortsrcarr[i] ^ shortxorarr[i];
283+ }
284+ break;
285+ case DataBuffer.TYPE_INT:
286+ int[] intsrcarr = (int[]) srcPixel;
287+ int[] intdstarr = (int[]) dstPixel;
288+ int[] intxorarr = (int[]) xorPixel;
289+ for (int i = 0; i < intdstarr.length; i++) {
290+ intdstarr[i] ^= intsrcarr[i] ^ intxorarr[i];
291+ }
292+ break;
293+ case DataBuffer.TYPE_FLOAT:
294+ float[] floatsrcarr = (float[]) srcPixel;
295+ float[] floatdstarr = (float[]) dstPixel;
296+ float[] floatxorarr = (float[]) xorPixel;
297+ for (int i = 0; i < floatdstarr.length; i++) {
298+ int v = (Float.floatToIntBits(floatdstarr[i]) ^
299+ Float.floatToIntBits(floatsrcarr[i]) ^
300+ Float.floatToIntBits(floatxorarr[i]));
301+ floatdstarr[i] = Float.intBitsToFloat(v);
302+ }
303+ break;
304+ case DataBuffer.TYPE_DOUBLE:
305+ double[] doublesrcarr = (double[]) srcPixel;
306+ double[] doubledstarr = (double[]) dstPixel;
307+ double[] doublexorarr = (double[]) xorPixel;
308+ for (int i = 0; i < doubledstarr.length; i++) {
309+ long v = (Double.doubleToLongBits(doubledstarr[i]) ^
310+ Double.doubleToLongBits(doublesrcarr[i]) ^
311+ Double.doubleToLongBits(doublexorarr[i]));
312+ doubledstarr[i] = Double.longBitsToDouble(v);
313+ }
314+ break;
315+ default:
316+ throw new InternalError("Unsupported XOR pixel type");
317+ }
318+ dstRast.setDataElements(x, y, dstPixel);
319+ }
320+ rowoff += srcScan;
321+ }
322+ }
323+ // REMIND: We need to do something to make sure that dstRast
324+ // is put back to the destination (as in the native Release
325+ // function)
326+ // src.releaseRaster(srcRast); // NOP?
327+ // dst.releaseRaster(dstRast);
328+ }
329+}
java/pkg/sun/java2d/loops/DrawGlyphList$General.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/DrawGlyphList$TraceDrawGlyphList.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/DrawGlyphList.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/DrawGlyphList.java+161−0
@@ -0,0 +1,161 @@
1+/*
2+ * Copyright (c) 2000, 2003, 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+
26+package sun.java2d.loops;
27+
28+import sun.java2d.loops.GraphicsPrimitive;
29+import sun.java2d.pipe.Region;
30+import sun.java2d.SunGraphics2D;
31+import sun.java2d.SurfaceData;
32+import sun.font.GlyphList;
33+
34+/**
35+ * DrawGlyphList - loops for SolidTextRenderer pipe.
36+ * 1) draw solid color text onto destination surface
37+ * 2) must accept output area [x, y, dx, dy]
38+ * from within the surface description data for clip rect
39+ */
40+public class DrawGlyphList extends GraphicsPrimitive {
41+
42+ public final static String methodSignature = "DrawGlyphList(...)".toString();
43+
44+ public final static int primTypeID = makePrimTypeID();
45+
46+ public static DrawGlyphList locate(SurfaceType srctype,
47+ CompositeType comptype,
48+ SurfaceType dsttype)
49+ {
50+ return (DrawGlyphList)
51+ GraphicsPrimitiveMgr.locate(primTypeID,
52+ srctype, comptype, dsttype);
53+ }
54+
55+ protected DrawGlyphList(SurfaceType srctype,
56+ CompositeType comptype,
57+ SurfaceType dsttype)
58+ {
59+ super(methodSignature, primTypeID, srctype, comptype, dsttype);
60+ }
61+
62+ public DrawGlyphList(long pNativePrim,
63+ SurfaceType srctype,
64+ CompositeType comptype,
65+ SurfaceType dsttype)
66+ {
67+ super(pNativePrim, methodSignature, primTypeID, srctype, comptype, dsttype);
68+ }
69+
70+
71+ public native void DrawGlyphList(SunGraphics2D sg2d, SurfaceData dest,
72+ GlyphList srcData);
73+
74+ // This instance is used only for lookup.
75+ static {
76+ GraphicsPrimitiveMgr.registerGeneral(
77+ new DrawGlyphList(null, null, null));
78+ }
79+
80+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
81+ CompositeType comptype,
82+ SurfaceType dsttype) {
83+ return new General(srctype, comptype, dsttype);
84+ }
85+
86+ private static class General extends DrawGlyphList {
87+ MaskFill maskop;
88+
89+ public General(SurfaceType srctype,
90+ CompositeType comptype,
91+ SurfaceType dsttype)
92+ {
93+ super(srctype, comptype, dsttype);
94+ maskop = MaskFill.locate(srctype, comptype, dsttype);
95+ }
96+
97+ public void DrawGlyphList(SunGraphics2D sg2d, SurfaceData dest,
98+ GlyphList gl) {
99+
100+ int strbounds[] = gl.getBounds(); // Don't delete, bug 4895493
101+ int num = gl.getNumGlyphs();
102+ Region clip = sg2d.getCompClip();
103+ int cx1 = clip.getLoX();
104+ int cy1 = clip.getLoY();
105+ int cx2 = clip.getHiX();
106+ int cy2 = clip.getHiY();
107+ for (int i = 0; i < num; i++) {
108+ gl.setGlyphIndex(i);
109+ int metrics[] = gl.getMetrics();
110+ int gx1 = metrics[0];
111+ int gy1 = metrics[1];
112+ int w = metrics[2];
113+ int gx2 = gx1 + w;
114+ int gy2 = gy1 + metrics[3];
115+ int off = 0;
116+ if (gx1 < cx1) {
117+ off = cx1 - gx1;
118+ gx1 = cx1;
119+ }
120+ if (gy1 < cy1) {
121+ off += (cy1 - gy1) * w;
122+ gy1 = cy1;
123+ }
124+ if (gx2 > cx2) gx2 = cx2;
125+ if (gy2 > cy2) gy2 = cy2;
126+ if (gx2 > gx1 && gy2 > gy1) {
127+ byte alpha[] = gl.getGrayBits();
128+ maskop.MaskFill(sg2d, dest, sg2d.composite,
129+ gx1, gy1, gx2 - gx1, gy2 - gy1,
130+ alpha, off, w);
131+ }
132+ }
133+ }
134+ }
135+
136+ public GraphicsPrimitive traceWrap() {
137+ return new TraceDrawGlyphList(this);
138+ }
139+
140+ private static class TraceDrawGlyphList extends DrawGlyphList {
141+ DrawGlyphList target;
142+
143+ public TraceDrawGlyphList(DrawGlyphList target) {
144+ super(target.getSourceType(),
145+ target.getCompositeType(),
146+ target.getDestType());
147+ this.target = target;
148+ }
149+
150+ public GraphicsPrimitive traceWrap() {
151+ return this;
152+ }
153+
154+ public void DrawGlyphList(SunGraphics2D sg2d, SurfaceData dest,
155+ GlyphList glyphs)
156+ {
157+ tracePrimitive(target);
158+ target.DrawGlyphList(sg2d, dest, glyphs);
159+ }
160+ }
161+}
java/pkg/sun/java2d/loops/DrawGlyphListAA$General.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/DrawGlyphListAA$TraceDrawGlyphListAA.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/DrawGlyphListAA.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/DrawGlyphListAA.java+159−0
@@ -0,0 +1,159 @@
1+/*
2+ * Copyright (c) 2000, 2004, 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+
26+package sun.java2d.loops;
27+
28+import sun.java2d.loops.GraphicsPrimitive;
29+import sun.java2d.pipe.Region;
30+import sun.java2d.SunGraphics2D;
31+import sun.java2d.SurfaceData;
32+import sun.font.GlyphList;
33+
34+/**
35+ * DrawGlyphListAA - loops for AATextRenderer pipe
36+ * 1) draw anti-aliased text onto destination surface
37+ * 2) must accept output area [x, y, dx, dy]
38+ * from within the surface description data for clip rect
39+ */
40+public class DrawGlyphListAA extends GraphicsPrimitive {
41+
42+ public final static String methodSignature = "DrawGlyphListAA(...)".toString();
43+
44+ public final static int primTypeID = makePrimTypeID();
45+
46+ public static DrawGlyphListAA locate(SurfaceType srctype,
47+ CompositeType comptype,
48+ SurfaceType dsttype)
49+ {
50+ return (DrawGlyphListAA)
51+ GraphicsPrimitiveMgr.locate(primTypeID,
52+ srctype, comptype, dsttype);
53+ }
54+
55+ protected DrawGlyphListAA(SurfaceType srctype,
56+ CompositeType comptype,
57+ SurfaceType dsttype)
58+ {
59+ super(methodSignature, primTypeID, srctype, comptype, dsttype);
60+ }
61+
62+ public DrawGlyphListAA(long pNativePrim,
63+ SurfaceType srctype,
64+ CompositeType comptype,
65+ SurfaceType dsttype)
66+ {
67+ super(pNativePrim, methodSignature, primTypeID, srctype, comptype, dsttype);
68+ }
69+
70+ public native void DrawGlyphListAA(SunGraphics2D sg2d, SurfaceData dest,
71+ GlyphList srcData);
72+
73+ static {
74+ GraphicsPrimitiveMgr.registerGeneral(
75+ new DrawGlyphListAA(null, null, null));
76+ }
77+
78+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
79+ CompositeType comptype,
80+ SurfaceType dsttype) {
81+ return new General(srctype, comptype, dsttype);
82+ }
83+
84+ public static class General extends DrawGlyphListAA {
85+ MaskFill maskop;
86+
87+ public General(SurfaceType srctype,
88+ CompositeType comptype,
89+ SurfaceType dsttype)
90+ {
91+ super(srctype, comptype, dsttype);
92+ maskop = MaskFill.locate(srctype, comptype, dsttype);
93+ }
94+
95+ public void DrawGlyphListAA(SunGraphics2D sg2d, SurfaceData dest,
96+ GlyphList gl)
97+ {
98+ gl.getBounds(); // Don't delete, bug 4895493
99+ int num = gl.getNumGlyphs();
100+ Region clip = sg2d.getCompClip();
101+ int cx1 = clip.getLoX();
102+ int cy1 = clip.getLoY();
103+ int cx2 = clip.getHiX();
104+ int cy2 = clip.getHiY();
105+ for (int i = 0; i < num; i++) {
106+ gl.setGlyphIndex(i);
107+ int metrics[] = gl.getMetrics();
108+ int gx1 = metrics[0];
109+ int gy1 = metrics[1];
110+ int w = metrics[2];
111+ int gx2 = gx1 + w;
112+ int gy2 = gy1 + metrics[3];
113+ int off = 0;
114+ if (gx1 < cx1) {
115+ off = cx1 - gx1;
116+ gx1 = cx1;
117+ }
118+ if (gy1 < cy1) {
119+ off += (cy1 - gy1) * w;
120+ gy1 = cy1;
121+ }
122+ if (gx2 > cx2) gx2 = cx2;
123+ if (gy2 > cy2) gy2 = cy2;
124+ if (gx2 > gx1 && gy2 > gy1) {
125+ byte alpha[] = gl.getGrayBits();
126+ maskop.MaskFill(sg2d, dest, sg2d.composite,
127+ gx1, gy1, gx2 - gx1, gy2 - gy1,
128+ alpha, off, w);
129+ }
130+ }
131+ }
132+ }
133+
134+ public GraphicsPrimitive traceWrap() {
135+ return new TraceDrawGlyphListAA(this);
136+ }
137+
138+ private static class TraceDrawGlyphListAA extends DrawGlyphListAA {
139+ DrawGlyphListAA target;
140+
141+ public TraceDrawGlyphListAA(DrawGlyphListAA target) {
142+ super(target.getSourceType(),
143+ target.getCompositeType(),
144+ target.getDestType());
145+ this.target = target;
146+ }
147+
148+ public GraphicsPrimitive traceWrap() {
149+ return this;
150+ }
151+
152+ public void DrawGlyphListAA(SunGraphics2D sg2d, SurfaceData dest,
153+ GlyphList glyphs)
154+ {
155+ tracePrimitive(target);
156+ target.DrawGlyphListAA(sg2d, dest, glyphs);
157+ }
158+ }
159+}
java/pkg/sun/java2d/loops/DrawGlyphListLCD$TraceDrawGlyphListLCD.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/DrawGlyphListLCD.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/DrawGlyphListLCD.java+117−0
@@ -0,0 +1,117 @@
1+/*
2+ * Copyright (c) 2005, 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+
26+package sun.java2d.loops;
27+
28+import sun.java2d.loops.GraphicsPrimitive;
29+import sun.java2d.pipe.Region;
30+import sun.java2d.SunGraphics2D;
31+import sun.java2d.SurfaceData;
32+import sun.font.GlyphList;
33+
34+/**
35+ * DrawGlyphListLCD- loops for LCDTextRenderer pipe
36+ * 1) draw LCD anti-aliased text onto destination surface
37+ * 2) must accept output area [x, y, dx, dy]
38+ * from within the surface description data for clip rect
39+ */
40+public class DrawGlyphListLCD extends GraphicsPrimitive {
41+
42+ public final static String
43+ methodSignature = "DrawGlyphListLCD(...)".toString();
44+
45+ public final static int primTypeID = makePrimTypeID();
46+
47+ public static DrawGlyphListLCD locate(SurfaceType srctype,
48+ CompositeType comptype,
49+ SurfaceType dsttype)
50+ {
51+ return (DrawGlyphListLCD)
52+ GraphicsPrimitiveMgr.locate(primTypeID,
53+ srctype, comptype, dsttype);
54+ }
55+
56+ protected DrawGlyphListLCD(SurfaceType srctype,
57+ CompositeType comptype,
58+ SurfaceType dsttype)
59+ {
60+ super(methodSignature, primTypeID, srctype, comptype, dsttype);
61+ }
62+
63+ public DrawGlyphListLCD(long pNativePrim,
64+ SurfaceType srctype,
65+ CompositeType comptype,
66+ SurfaceType dsttype)
67+ {
68+ super(pNativePrim, methodSignature, primTypeID,
69+ srctype, comptype, dsttype);
70+ }
71+
72+ public native void DrawGlyphListLCD(SunGraphics2D sg2d, SurfaceData dest,
73+ GlyphList srcData);
74+
75+ static {
76+ GraphicsPrimitiveMgr.registerGeneral(
77+ new DrawGlyphListLCD(null, null, null));
78+ }
79+
80+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
81+ CompositeType comptype,
82+ SurfaceType dsttype) {
83+ /* Do not return a General loop. SunGraphics2D determines whether
84+ * to use LCD or standard AA text based on whether there is an
85+ * installed loop.
86+ * This can be uncommented once there is a General loop which can
87+ * handle one byte per colour component masks properly.
88+ */
89+ return null;
90+ }
91+
92+ public GraphicsPrimitive traceWrap() {
93+ return new TraceDrawGlyphListLCD(this);
94+ }
95+
96+ private static class TraceDrawGlyphListLCD extends DrawGlyphListLCD {
97+ DrawGlyphListLCD target;
98+
99+ public TraceDrawGlyphListLCD(DrawGlyphListLCD target) {
100+ super(target.getSourceType(),
101+ target.getCompositeType(),
102+ target.getDestType());
103+ this.target = target;
104+ }
105+
106+ public GraphicsPrimitive traceWrap() {
107+ return this;
108+ }
109+
110+ public void DrawGlyphListLCD(SunGraphics2D sg2d, SurfaceData dest,
111+ GlyphList glyphs)
112+ {
113+ tracePrimitive(target);
114+ target.DrawGlyphListLCD(sg2d, dest, glyphs);
115+ }
116+ }
117+}
java/pkg/sun/java2d/loops/DrawLine$TraceDrawLine.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/DrawLine.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/DrawLine.java+114−0
@@ -0,0 +1,114 @@
1+/*
2+ * Copyright (c) 1997, 2002, 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+
26+/*
27+ * @author Charlton Innovations, Inc.
28+ */
29+
30+package sun.java2d.loops;
31+
32+import sun.java2d.loops.GraphicsPrimitive;
33+import java.awt.Color;
34+import java.awt.image.ColorModel;
35+import java.awt.image.Raster;
36+import sun.java2d.SunGraphics2D;
37+import sun.java2d.SurfaceData;
38+
39+/**
40+ * DrawLine
41+ * 1) draw solid color single width line onto destination surface
42+ * 2) must accept output area [x, y, dx, dy]
43+ * from within the surface description data for clip rect
44+ */
45+public class DrawLine extends GraphicsPrimitive
46+{
47+ public final static String methodSignature = "DrawLine(...)".toString();
48+
49+ public final static int primTypeID = makePrimTypeID();
50+
51+ public static DrawLine locate(SurfaceType srctype,
52+ CompositeType comptype,
53+ SurfaceType dsttype)
54+ {
55+ return (DrawLine) GraphicsPrimitiveMgr.locate(primTypeID,
56+ srctype, comptype, dsttype);
57+ }
58+
59+ protected DrawLine(SurfaceType srctype,
60+ CompositeType comptype,
61+ SurfaceType dsttype)
62+ {
63+ super(methodSignature, primTypeID, srctype, comptype, dsttype);
64+ }
65+
66+ public DrawLine(long pNativePrim,
67+ SurfaceType srctype,
68+ CompositeType comptype,
69+ SurfaceType dsttype)
70+ {
71+ super(pNativePrim, methodSignature, primTypeID, srctype, comptype, dsttype);
72+ }
73+
74+ /**
75+ * All DrawLine implementors must have this invoker method
76+ */
77+ public native void DrawLine(SunGraphics2D sg2d, SurfaceData dest,
78+ int x1, int y1, int x2, int y2);
79+
80+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
81+ CompositeType comptype,
82+ SurfaceType dsttype)
83+ {
84+ // REMIND: use FillSpans or converter object?
85+ throw new InternalError("DrawLine not implemented for "+
86+ srctype+" with "+comptype);
87+ }
88+
89+ public GraphicsPrimitive traceWrap() {
90+ return new TraceDrawLine(this);
91+ }
92+
93+ private static class TraceDrawLine extends DrawLine {
94+ DrawLine target;
95+
96+ public TraceDrawLine(DrawLine target) {
97+ super(target.getSourceType(),
98+ target.getCompositeType(),
99+ target.getDestType());
100+ this.target = target;
101+ }
102+
103+ public GraphicsPrimitive traceWrap() {
104+ return this;
105+ }
106+
107+ public void DrawLine(SunGraphics2D sg2d, SurfaceData dest,
108+ int x1, int y1, int x2, int y2)
109+ {
110+ tracePrimitive(target);
111+ target.DrawLine(sg2d, dest, x1, y1, x2, y2);
112+ }
113+ }
114+}
java/pkg/sun/java2d/loops/DrawParallelogram$TraceDrawParallelogram.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/DrawParallelogram.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/DrawParallelogram.java+123−0
@@ -0,0 +1,123 @@
1+/*
2+ * Copyright (c) 2008, 2010, 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+
26+/*
27+ * @author Jim Graham
28+ */
29+
30+package sun.java2d.loops;
31+
32+import sun.java2d.loops.GraphicsPrimitive;
33+import sun.java2d.SunGraphics2D;
34+import sun.java2d.SurfaceData;
35+
36+/**
37+ * DrawParallelogram
38+ * 1) fill the area between the 4 edges of an outer parallelogram
39+ * (as specified by an origin and 2 delta vectors)
40+ * but also outside the 4 edges of an inner parallelogram
41+ * (as specified by proportional amounts of the outer delta vectors)
42+ */
43+public class DrawParallelogram extends GraphicsPrimitive
44+{
45+ public final static String methodSignature =
46+ "DrawParallelogram(...)".toString();
47+
48+ public final static int primTypeID = makePrimTypeID();
49+
50+ public static DrawParallelogram locate(SurfaceType srctype,
51+ CompositeType comptype,
52+ SurfaceType dsttype)
53+ {
54+ return (DrawParallelogram)
55+ GraphicsPrimitiveMgr.locate(primTypeID,
56+ srctype, comptype, dsttype);
57+ }
58+
59+ protected DrawParallelogram(SurfaceType srctype,
60+ CompositeType comptype,
61+ SurfaceType dsttype)
62+ {
63+ super(methodSignature, primTypeID,
64+ srctype, comptype, dsttype);
65+ }
66+
67+ public DrawParallelogram(long pNativePrim,
68+ SurfaceType srctype,
69+ CompositeType comptype,
70+ SurfaceType dsttype)
71+ {
72+ super(pNativePrim, methodSignature, primTypeID,
73+ srctype, comptype, dsttype);
74+ }
75+
76+ /**
77+ * All DrawParallelogram implementors must have this invoker method
78+ */
79+ public native void DrawParallelogram(SunGraphics2D sg, SurfaceData dest,
80+ double x, double y,
81+ double dx1, double dy1,
82+ double dx2, double dy2,
83+ double lw1, double lw2);
84+
85+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
86+ CompositeType comptype,
87+ SurfaceType dsttype)
88+ {
89+ // REMIND: iterate with a FillRect primitive?
90+ throw new InternalError("DrawParallelogram not implemented for "+
91+ srctype+" with "+comptype);
92+ }
93+
94+ public GraphicsPrimitive traceWrap() {
95+ return new TraceDrawParallelogram(this);
96+ }
97+
98+ private static class TraceDrawParallelogram extends DrawParallelogram {
99+ DrawParallelogram target;
100+
101+ public TraceDrawParallelogram(DrawParallelogram target) {
102+ super(target.getSourceType(),
103+ target.getCompositeType(),
104+ target.getDestType());
105+ this.target = target;
106+ }
107+
108+ public GraphicsPrimitive traceWrap() {
109+ return this;
110+ }
111+
112+ public void DrawParallelogram(SunGraphics2D sg2d, SurfaceData dest,
113+ double x, double y,
114+ double dx1, double dy1,
115+ double dx2, double dy2,
116+ double lw1, double lw2)
117+ {
118+ tracePrimitive(target);
119+ target.DrawParallelogram(sg2d, dest,
120+ x, y, dx1, dy1, dx2, dy2, lw1, lw2);
121+ }
122+ }
123+}
java/pkg/sun/java2d/loops/DrawPath$TraceDrawPath.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/DrawPath.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/DrawPath.java+114−0
@@ -0,0 +1,114 @@
1+/*
2+ * Copyright (c) 2005, 2006, 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+
26+package sun.java2d.loops;
27+
28+import sun.java2d.loops.GraphicsPrimitive;
29+import sun.java2d.SunGraphics2D;
30+import sun.java2d.SurfaceData;
31+import java.awt.geom.Path2D;
32+
33+/**
34+ * DrawPath
35+ * 1. draw single-width line path onto destination surface
36+ * 2. must accept output area [x, y, dx, dy]
37+ * from within the surface description data for clip rect
38+ */
39+public class DrawPath extends GraphicsPrimitive {
40+
41+ public final static String methodSignature =
42+ "DrawPath(...)".toString();
43+
44+ public final static int primTypeID = makePrimTypeID();
45+
46+ public static DrawPath locate(SurfaceType srctype,
47+ CompositeType comptype,
48+ SurfaceType dsttype)
49+ {
50+ return (DrawPath)
51+ GraphicsPrimitiveMgr.locate(primTypeID,
52+ srctype, comptype, dsttype);
53+ }
54+
55+ protected DrawPath(SurfaceType srctype,
56+ CompositeType comptype,
57+ SurfaceType dsttype)
58+ {
59+ super(methodSignature, primTypeID,
60+ srctype, comptype, dsttype);
61+ }
62+
63+ public DrawPath(long pNativePrim,
64+ SurfaceType srctype,
65+ CompositeType comptype,
66+ SurfaceType dsttype)
67+ {
68+ super(pNativePrim, methodSignature, primTypeID,
69+ srctype, comptype, dsttype);
70+ }
71+
72+
73+ /**
74+ * All DrawPath implementors must have this invoker method
75+ */
76+ public native void DrawPath(SunGraphics2D sg2d, SurfaceData sData,
77+ int transX, int transY,
78+ Path2D.Float p2df);
79+
80+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
81+ CompositeType comptype,
82+ SurfaceType dsttype)
83+ {
84+ throw new InternalError("DrawPath not implemented for "+
85+ srctype+" with "+comptype);
86+ }
87+
88+ public GraphicsPrimitive traceWrap() {
89+ return new TraceDrawPath(this);
90+ }
91+
92+ private static class TraceDrawPath extends DrawPath {
93+ DrawPath target;
94+
95+ public TraceDrawPath(DrawPath target) {
96+ super(target.getSourceType(),
97+ target.getCompositeType(),
98+ target.getDestType());
99+ this.target = target;
100+ }
101+
102+ public GraphicsPrimitive traceWrap() {
103+ return this;
104+ }
105+
106+ public void DrawPath(SunGraphics2D sg2d, SurfaceData sData,
107+ int transX, int transY,
108+ Path2D.Float p2df)
109+ {
110+ tracePrimitive(target);
111+ target.DrawPath(sg2d, sData, transX, transY, p2df);
112+ }
113+ }
114+}
java/pkg/sun/java2d/loops/DrawPolygons$TraceDrawPolygons.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/DrawPolygons.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/DrawPolygons.java+120−0
@@ -0,0 +1,120 @@
1+/*
2+ * Copyright (c) 1997, 2002, 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+
26+/*
27+ * @author Charlton Innovations, Inc.
28+ */
29+
30+package sun.java2d.loops;
31+
32+import sun.java2d.loops.GraphicsPrimitive;
33+import sun.java2d.SunGraphics2D;
34+import sun.java2d.SurfaceData;
35+
36+/**
37+ * DrawPolygons
38+ * 1) draw single-width line polygons onto destination surface
39+ * 2) must accept output area [x, y, dx, dy]
40+ * from within the surface description data for clip rect
41+ */
42+public class DrawPolygons extends GraphicsPrimitive
43+{
44+ public final static String methodSignature = "DrawPolygons(...)".toString();
45+
46+ public final static int primTypeID = makePrimTypeID();
47+
48+ public static DrawPolygons locate(SurfaceType srctype,
49+ CompositeType comptype,
50+ SurfaceType dsttype)
51+ {
52+ return (DrawPolygons)
53+ GraphicsPrimitiveMgr.locate(primTypeID,
54+ srctype, comptype, dsttype);
55+ }
56+
57+ protected DrawPolygons(SurfaceType srctype,
58+ CompositeType comptype,
59+ SurfaceType dsttype)
60+ {
61+ super(methodSignature, primTypeID, srctype, comptype, dsttype);
62+ }
63+
64+ public DrawPolygons(long pNativePrim,
65+ SurfaceType srctype,
66+ CompositeType comptype,
67+ SurfaceType dsttype)
68+ {
69+ super(pNativePrim, methodSignature, primTypeID, srctype, comptype, dsttype);
70+ }
71+
72+ /**
73+ * All DrawPolygon implementors must have this invoker method
74+ */
75+ public native void DrawPolygons(SunGraphics2D sg2d, SurfaceData sData,
76+ int xPoints[], int yPoints[],
77+ int nPoints[], int numPolys,
78+ int transX, int transY,
79+ boolean close);
80+
81+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
82+ CompositeType comptype,
83+ SurfaceType dsttype)
84+ {
85+ // REMIND: use FillSpans or converter object?
86+ throw new InternalError("DrawPolygons not implemented for "+
87+ srctype+" with "+comptype);
88+ }
89+
90+ public GraphicsPrimitive traceWrap() {
91+ return new TraceDrawPolygons(this);
92+ }
93+
94+ private static class TraceDrawPolygons extends DrawPolygons {
95+ DrawPolygons target;
96+
97+ public TraceDrawPolygons(DrawPolygons target) {
98+ super(target.getSourceType(),
99+ target.getCompositeType(),
100+ target.getDestType());
101+ this.target = target;
102+ }
103+
104+ public GraphicsPrimitive traceWrap() {
105+ return this;
106+ }
107+
108+ public void DrawPolygons(SunGraphics2D sg2d, SurfaceData sData,
109+ int xPoints[], int yPoints[],
110+ int nPoints[], int numPolys,
111+ int transX, int transY,
112+ boolean close)
113+ {
114+ tracePrimitive(target);
115+ target.DrawPolygons(sg2d, sData,
116+ xPoints, yPoints, nPoints, numPolys,
117+ transX, transY, close);
118+ }
119+ }
120+}
java/pkg/sun/java2d/loops/DrawRect$TraceDrawRect.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/DrawRect.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/DrawRect.java+115−0
@@ -0,0 +1,115 @@
1+/*
2+ * Copyright (c) 1997, 2002, 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+
26+/*
27+ * @author Charlton Innovations, Inc.
28+ */
29+
30+package sun.java2d.loops;
31+
32+import sun.java2d.loops.GraphicsPrimitive;
33+import java.awt.Color;
34+import java.awt.image.ColorModel;
35+import java.awt.image.Raster;
36+import sun.java2d.SunGraphics2D;
37+import sun.java2d.SurfaceData;
38+
39+/**
40+ * DrawRect
41+ * 1) draw single-width line rectangle onto destination surface
42+ * 2) must accept output area [x, y, dx, dy]
43+ * from within the surface description data for clip rect
44+ */
45+public class DrawRect extends GraphicsPrimitive
46+{
47+ public final static String methodSignature = "DrawRect(...)".toString();
48+
49+ public final static int primTypeID = makePrimTypeID();
50+
51+ public static DrawRect locate(SurfaceType srctype,
52+ CompositeType comptype,
53+ SurfaceType dsttype)
54+ {
55+ return (DrawRect)
56+ GraphicsPrimitiveMgr.locate(primTypeID,
57+ srctype, comptype, dsttype);
58+ }
59+
60+ protected DrawRect(SurfaceType srctype,
61+ CompositeType comptype,
62+ SurfaceType dsttype)
63+ {
64+ super(methodSignature, primTypeID, srctype, comptype, dsttype);
65+ }
66+
67+ public DrawRect(long pNativePrim,
68+ SurfaceType srctype,
69+ CompositeType comptype,
70+ SurfaceType dsttype)
71+ {
72+ super(pNativePrim, methodSignature, primTypeID, srctype, comptype, dsttype);
73+ }
74+
75+ /**
76+ * All DrawRect implementors must have this invoker method
77+ */
78+ public native void DrawRect(SunGraphics2D sg2d, SurfaceData dest,
79+ int x1, int y1, int w, int h);
80+
81+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
82+ CompositeType comptype,
83+ SurfaceType dsttype)
84+ {
85+ // REMIND: use FillSpans or converter object?
86+ throw new InternalError("DrawRect not implemented for "+
87+ srctype+" with "+comptype);
88+ }
89+
90+ public GraphicsPrimitive traceWrap() {
91+ return new TraceDrawRect(this);
92+ }
93+
94+ private static class TraceDrawRect extends DrawRect {
95+ DrawRect target;
96+
97+ public TraceDrawRect(DrawRect target) {
98+ super(target.getSourceType(),
99+ target.getCompositeType(),
100+ target.getDestType());
101+ this.target = target;
102+ }
103+
104+ public GraphicsPrimitive traceWrap() {
105+ return this;
106+ }
107+
108+ public void DrawRect(SunGraphics2D sg2d, SurfaceData dest,
109+ int x1, int y1, int w, int h)
110+ {
111+ tracePrimitive(target);
112+ target.DrawRect(sg2d, dest, x1, y1, w, h);
113+ }
114+ }
115+}
java/pkg/sun/java2d/loops/FillParallelogram$TraceFillParallelogram.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/FillParallelogram.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/FillParallelogram.java+118−0
@@ -0,0 +1,118 @@
1+/*
2+ * Copyright (c) 2008, 2010, 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+
26+/*
27+ * @author Jim Graham
28+ */
29+
30+package sun.java2d.loops;
31+
32+import sun.java2d.loops.GraphicsPrimitive;
33+import sun.java2d.SunGraphics2D;
34+import sun.java2d.SurfaceData;
35+
36+/**
37+ * FillParallelogram
38+ * 1) fill the area between the 4 edges of a parallelogram
39+ * (as specified by an origin and 2 delta vectors)
40+ */
41+public class FillParallelogram extends GraphicsPrimitive
42+{
43+ public final static String methodSignature =
44+ "FillParallelogram(...)".toString();
45+
46+ public final static int primTypeID = makePrimTypeID();
47+
48+ public static FillParallelogram locate(SurfaceType srctype,
49+ CompositeType comptype,
50+ SurfaceType dsttype)
51+ {
52+ return (FillParallelogram)
53+ GraphicsPrimitiveMgr.locate(primTypeID,
54+ srctype, comptype, dsttype);
55+ }
56+
57+ protected FillParallelogram(SurfaceType srctype,
58+ CompositeType comptype,
59+ SurfaceType dsttype)
60+ {
61+ super(methodSignature, primTypeID,
62+ srctype, comptype, dsttype);
63+ }
64+
65+ public FillParallelogram(long pNativePrim,
66+ SurfaceType srctype,
67+ CompositeType comptype,
68+ SurfaceType dsttype)
69+ {
70+ super(pNativePrim, methodSignature, primTypeID,
71+ srctype, comptype, dsttype);
72+ }
73+
74+ /**
75+ * All FillParallelogram implementors must have this invoker method
76+ */
77+ public native void FillParallelogram(SunGraphics2D sg2d, SurfaceData dest,
78+ double x0, double y0,
79+ double dx1, double dy1,
80+ double dx2, double dy2);
81+
82+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
83+ CompositeType comptype,
84+ SurfaceType dsttype)
85+ {
86+ // REMIND: iterate with a FillRect primitive?
87+ throw new InternalError("FillParallelogram not implemented for "+
88+ srctype+" with "+comptype);
89+ }
90+
91+ public GraphicsPrimitive traceWrap() {
92+ return new TraceFillParallelogram(this);
93+ }
94+
95+ private static class TraceFillParallelogram extends FillParallelogram {
96+ FillParallelogram target;
97+
98+ public TraceFillParallelogram(FillParallelogram target) {
99+ super(target.getSourceType(),
100+ target.getCompositeType(),
101+ target.getDestType());
102+ this.target = target;
103+ }
104+
105+ public GraphicsPrimitive traceWrap() {
106+ return this;
107+ }
108+
109+ public void FillParallelogram(SunGraphics2D sg2d, SurfaceData dest,
110+ double x0, double y0,
111+ double dx1, double dy1,
112+ double dx2, double dy2)
113+ {
114+ tracePrimitive(target);
115+ target.FillParallelogram(sg2d, dest, x0, y0, dx1, dy1, dx2, dy2);
116+ }
117+ }
118+}
java/pkg/sun/java2d/loops/FillPath$TraceFillPath.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/FillPath.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/FillPath.java+114−0
@@ -0,0 +1,114 @@
1+/*
2+ * Copyright (c) 2005, 2006, 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+
26+package sun.java2d.loops;
27+
28+import sun.java2d.loops.GraphicsPrimitive;
29+import sun.java2d.SunGraphics2D;
30+import sun.java2d.SurfaceData;
31+import java.awt.geom.Path2D;
32+
33+/**
34+ * FillPath
35+ * 1. fill path onto destination surface
36+ * 2. must accept output area [x, y, dx, dy]
37+ * from within the surface description data for clip rect
38+ */
39+public class FillPath extends GraphicsPrimitive {
40+
41+ public final static String methodSignature =
42+ "FillPath(...)".toString();
43+
44+ public final static int primTypeID = makePrimTypeID();
45+
46+ public static FillPath locate(SurfaceType srctype,
47+ CompositeType comptype,
48+ SurfaceType dsttype)
49+ {
50+ return (FillPath)
51+ GraphicsPrimitiveMgr.locate(primTypeID,
52+ srctype, comptype, dsttype);
53+ }
54+
55+ protected FillPath(SurfaceType srctype,
56+ CompositeType comptype,
57+ SurfaceType dsttype)
58+ {
59+ super(methodSignature, primTypeID,
60+ srctype, comptype, dsttype);
61+ }
62+
63+ public FillPath(long pNativePrim,
64+ SurfaceType srctype,
65+ CompositeType comptype,
66+ SurfaceType dsttype)
67+ {
68+ super(pNativePrim, methodSignature, primTypeID,
69+ srctype, comptype, dsttype);
70+ }
71+
72+
73+ /**
74+ * All FillPath implementors must have this invoker method
75+ */
76+ public native void FillPath(SunGraphics2D sg2d, SurfaceData sData,
77+ int transX, int transY,
78+ Path2D.Float p2df);
79+
80+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
81+ CompositeType comptype,
82+ SurfaceType dsttype)
83+ {
84+ throw new InternalError("FillPath not implemented for "+
85+ srctype+" with "+comptype);
86+ }
87+
88+ public GraphicsPrimitive traceWrap() {
89+ return new TraceFillPath(this);
90+ }
91+
92+ private static class TraceFillPath extends FillPath {
93+ FillPath target;
94+
95+ public TraceFillPath(FillPath target) {
96+ super(target.getSourceType(),
97+ target.getCompositeType(),
98+ target.getDestType());
99+ this.target = target;
100+ }
101+
102+ public GraphicsPrimitive traceWrap() {
103+ return this;
104+ }
105+
106+ public void FillPath(SunGraphics2D sg2d, SurfaceData sData,
107+ int transX, int transY,
108+ Path2D.Float p2df)
109+ {
110+ tracePrimitive(target);
111+ target.FillPath(sg2d, sData, transX, transY, p2df);
112+ }
113+ }
114+}
java/pkg/sun/java2d/loops/FillRect$General.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/FillRect$TraceFillRect.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/FillRect.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/FillRect.java+135−0
@@ -0,0 +1,135 @@
1+/*
2+ * Copyright (c) 1997, 2002, 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+
26+/*
27+ * @author Charlton Innovations, Inc.
28+ */
29+
30+package sun.java2d.loops;
31+
32+import sun.java2d.loops.GraphicsPrimitive;
33+import java.awt.Color;
34+import java.awt.image.ColorModel;
35+import java.awt.image.Raster;
36+import sun.java2d.SunGraphics2D;
37+import sun.java2d.SurfaceData;
38+
39+/**
40+ * FillRect
41+ * 1) draw solid color rectangle onto destination surface
42+ * 2) must accept output area [x, y, dx, dy]
43+ * from within the surface description data for clip rect
44+ */
45+public class FillRect extends GraphicsPrimitive
46+{
47+ public final static String methodSignature = "FillRect(...)".toString();
48+
49+ public final static int primTypeID = makePrimTypeID();
50+
51+ public static FillRect locate(SurfaceType srctype,
52+ CompositeType comptype,
53+ SurfaceType dsttype)
54+ {
55+ return (FillRect)
56+ GraphicsPrimitiveMgr.locate(primTypeID,
57+ srctype, comptype, dsttype);
58+ }
59+
60+ protected FillRect(SurfaceType srctype,
61+ CompositeType comptype,
62+ SurfaceType dsttype)
63+ {
64+ super(methodSignature, primTypeID, srctype, comptype, dsttype);
65+ }
66+
67+ public FillRect(long pNativePrim,
68+ SurfaceType srctype,
69+ CompositeType comptype,
70+ SurfaceType dsttype)
71+ {
72+ super(pNativePrim, methodSignature, primTypeID, srctype, comptype, dsttype);
73+ }
74+
75+ /**
76+ * All FillRect implementors must have this invoker method
77+ */
78+ public native void FillRect(SunGraphics2D sg2d, SurfaceData dest,
79+ int x, int y, int w, int h);
80+
81+ static {
82+ GraphicsPrimitiveMgr.registerGeneral(new FillRect(null, null, null));
83+ }
84+
85+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
86+ CompositeType comptype,
87+ SurfaceType dsttype)
88+ {
89+ return new General(srctype, comptype, dsttype);
90+ }
91+
92+ public static class General extends FillRect {
93+ public MaskFill fillop;
94+
95+ public General(SurfaceType srctype,
96+ CompositeType comptype,
97+ SurfaceType dsttype)
98+ {
99+ super(srctype, comptype, dsttype);
100+ fillop = MaskFill.locate(srctype, comptype, dsttype);
101+ }
102+
103+ public void FillRect(SunGraphics2D sg2d, SurfaceData dest,
104+ int x, int y, int w, int h)
105+ {
106+ fillop.MaskFill(sg2d, dest, sg2d.composite, x, y, w, h, null, 0, 0);
107+ }
108+ }
109+
110+ public GraphicsPrimitive traceWrap() {
111+ return new TraceFillRect(this);
112+ }
113+
114+ private static class TraceFillRect extends FillRect {
115+ FillRect target;
116+
117+ public TraceFillRect(FillRect target) {
118+ super(target.getSourceType(),
119+ target.getCompositeType(),
120+ target.getDestType());
121+ this.target = target;
122+ }
123+
124+ public GraphicsPrimitive traceWrap() {
125+ return this;
126+ }
127+
128+ public void FillRect(SunGraphics2D sg2d, SurfaceData dest,
129+ int x, int y, int w, int h)
130+ {
131+ tracePrimitive(target);
132+ target.FillRect(sg2d, dest, x, y, w, h);
133+ }
134+ }
135+}
java/pkg/sun/java2d/loops/FillSpans$TraceFillSpans.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/FillSpans.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/FillSpans.java+122−0
@@ -0,0 +1,122 @@
1+/*
2+ * Copyright (c) 1998, 2002, 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+
26+ /*
27+ * @author Jim Graham
28+ * @author Charlton Innovations, Inc.
29+ */
30+
31+package sun.java2d.loops;
32+
33+import sun.java2d.loops.GraphicsPrimitive;
34+import sun.java2d.pipe.SpanIterator;
35+import java.awt.Color;
36+import java.awt.image.ColorModel;
37+import java.awt.image.Raster;
38+import sun.java2d.SunGraphics2D;
39+import sun.java2d.SurfaceData;
40+
41+/**
42+ * FillSpans
43+ * 1) draw solid color onto destination surface
44+ * 2) rectangular areas to fill come from SpanIterator
45+ */
46+public class FillSpans extends GraphicsPrimitive
47+{
48+ public final static String methodSignature = "FillSpans(...)".toString();
49+
50+ public final static int primTypeID = makePrimTypeID();
51+
52+ public static FillSpans locate(SurfaceType srctype,
53+ CompositeType comptype,
54+ SurfaceType dsttype)
55+ {
56+ return (FillSpans)
57+ GraphicsPrimitiveMgr.locate(primTypeID,
58+ srctype, comptype, dsttype);
59+ }
60+
61+ protected FillSpans(SurfaceType srctype,
62+ CompositeType comptype,
63+ SurfaceType dsttype)
64+ {
65+ super(methodSignature, primTypeID, srctype, comptype, dsttype);
66+ }
67+
68+ public FillSpans(long pNativePrim,
69+ SurfaceType srctype,
70+ CompositeType comptype,
71+ SurfaceType dsttype)
72+ {
73+ super(pNativePrim, methodSignature, primTypeID, srctype, comptype, dsttype);
74+ }
75+
76+ private native void FillSpans(SunGraphics2D sg2d, SurfaceData dest,
77+ int pixel, long pIterator, SpanIterator si);
78+
79+ /**
80+ * All FillSpan implementors must have this invoker method
81+ */
82+ public void FillSpans(SunGraphics2D sg2d, SurfaceData dest,
83+ SpanIterator si)
84+ {
85+ FillSpans(sg2d, dest, sg2d.pixel, si.getNativeIterator(), si);
86+ }
87+
88+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
89+ CompositeType comptype,
90+ SurfaceType dsttype)
91+ {
92+ // REMIND: iterate with a FillRect primitive?
93+ throw new InternalError("FillSpans not implemented for "+
94+ srctype+" with "+comptype);
95+ }
96+
97+ public GraphicsPrimitive traceWrap() {
98+ return new TraceFillSpans(this);
99+ }
100+
101+ private static class TraceFillSpans extends FillSpans {
102+ FillSpans target;
103+
104+ public TraceFillSpans(FillSpans target) {
105+ super(target.getSourceType(),
106+ target.getCompositeType(),
107+ target.getDestType());
108+ this.target = target;
109+ }
110+
111+ public GraphicsPrimitive traceWrap() {
112+ return this;
113+ }
114+
115+ public void FillSpans(SunGraphics2D sg2d, SurfaceData dest,
116+ SpanIterator si)
117+ {
118+ tracePrimitive(target);
119+ target.FillSpans(sg2d, dest, si);
120+ }
121+ }
122+}
java/pkg/sun/java2d/loops/FontInfo.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/FontInfo.java+89−0
@@ -0,0 +1,89 @@
1+/*
2+ * Copyright (c) 1999, 2005, 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+
26+package sun.java2d.loops;
27+
28+import java.awt.Font;
29+import java.awt.geom.AffineTransform;
30+
31+import sun.font.Font2D;
32+import sun.font.FontStrike;
33+import sun.font.FontStrikeDesc;
34+
35+/*
36+ * A FontInfo object holds all calculated or derived data needed
37+ * to handle rendering operations based on a particular set of
38+ * Graphics2D rendering attributes.
39+ * Note that this does not use a Font2DHandle, and also has a reference
40+ * to the strike which also references the Font2D.
41+ * So presently, until SG2D objects no longer reference this FontInfo,
42+ * there is still some potential for a bad Font2D to be used for a short
43+ * time. I am reluctant to add the overhead of that machinery here without
44+ * a proven benefit.
45+ */
46+public class FontInfo implements Cloneable {
47+ public Font font;
48+ public Font2D font2D;
49+ public FontStrike fontStrike;
50+ public double[] devTx;
51+ public double[] glyphTx;
52+ public int pixelHeight;
53+ public float originX;
54+ public float originY;
55+ public int aaHint;
56+ public boolean lcdRGBOrder;
57+ /* lcdSubPixPos is used if FM is ON for HRGB/HBGR LCD text mode */
58+ public boolean lcdSubPixPos;
59+
60+ public String mtx(double[] matrix) {
61+ return ("["+
62+ matrix[0]+", "+
63+ matrix[1]+", "+
64+ matrix[2]+", "+
65+ matrix[3]+
66+ "]");
67+ }
68+
69+ public Object clone() {
70+ try {
71+ return super.clone();
72+ } catch (CloneNotSupportedException e) {
73+ return null;
74+ }
75+ }
76+
77+ public String toString() {
78+ return ("FontInfo["+
79+ "font="+font+", "+
80+ "devTx="+mtx(devTx)+", "+
81+ "glyphTx="+mtx(glyphTx)+", "+
82+ "pixelHeight="+pixelHeight+", "+
83+ "origin=("+originX+","+originY+"), "+
84+ "aaHint="+aaHint+", "+
85+ "lcdRGBOrder="+(lcdRGBOrder ? "RGB" : "BGR")+
86+ "lcdSubPixPos="+lcdSubPixPos+
87+ "]");
88+ }
89+}
java/pkg/sun/java2d/loops/GeneralRenderer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/GeneralRenderer.java+1125−0
@@ -0,0 +1,1125 @@
1+/*
2+ * Copyright (c) 1998, 2008, 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+
26+/*
27+ * @author Charlton Innovations, Inc.
28+ */
29+
30+package sun.java2d.loops;
31+
32+import java.awt.image.WritableRaster;
33+import java.awt.image.DataBuffer;
34+import java.awt.image.ColorModel;
35+import java.awt.geom.Path2D;
36+import java.awt.geom.PathIterator;
37+import java.awt.geom.AffineTransform;
38+import sun.java2d.pipe.Region;
39+import sun.java2d.pipe.SpanIterator;
40+import sun.java2d.SunGraphics2D;
41+import sun.java2d.SurfaceData;
42+import sun.java2d.loops.ProcessPath;
43+import sun.font.GlyphList;
44+
45+/**
46+ * GeneralRenderer collection
47+ * Basically, a collection of components which permit basic
48+ * rendering to occur on rasters of any format
49+ */
50+
51+public final class GeneralRenderer {
52+ public static void register() {
53+ Class owner = GeneralRenderer.class;
54+ GraphicsPrimitive[] primitives = {
55+ new GraphicsPrimitiveProxy(owner, "SetFillRectANY",
56+ FillRect.methodSignature,
57+ FillRect.primTypeID,
58+ SurfaceType.AnyColor,
59+ CompositeType.SrcNoEa,
60+ SurfaceType.Any),
61+ new GraphicsPrimitiveProxy(owner, "SetFillPathANY",
62+ FillPath.methodSignature,
63+ FillPath.primTypeID,
64+ SurfaceType.AnyColor,
65+ CompositeType.SrcNoEa,
66+ SurfaceType.Any),
67+ new GraphicsPrimitiveProxy(owner, "SetFillSpansANY",
68+ FillSpans.methodSignature,
69+ FillSpans.primTypeID,
70+ SurfaceType.AnyColor,
71+ CompositeType.SrcNoEa,
72+ SurfaceType.Any),
73+ new GraphicsPrimitiveProxy(owner, "SetDrawLineANY",
74+ DrawLine.methodSignature,
75+ DrawLine.primTypeID,
76+ SurfaceType.AnyColor,
77+ CompositeType.SrcNoEa,
78+ SurfaceType.Any),
79+ new GraphicsPrimitiveProxy(owner, "SetDrawPolygonsANY",
80+ DrawPolygons.methodSignature,
81+ DrawPolygons.primTypeID,
82+ SurfaceType.AnyColor,
83+ CompositeType.SrcNoEa,
84+ SurfaceType.Any),
85+ new GraphicsPrimitiveProxy(owner, "SetDrawPathANY",
86+ DrawPath.methodSignature,
87+ DrawPath.primTypeID,
88+ SurfaceType.AnyColor,
89+ CompositeType.SrcNoEa,
90+ SurfaceType.Any),
91+ new GraphicsPrimitiveProxy(owner, "SetDrawRectANY",
92+ DrawRect.methodSignature,
93+ DrawRect.primTypeID,
94+ SurfaceType.AnyColor,
95+ CompositeType.SrcNoEa,
96+ SurfaceType.Any),
97+
98+ new GraphicsPrimitiveProxy(owner, "XorFillRectANY",
99+ FillRect.methodSignature,
100+ FillRect.primTypeID,
101+ SurfaceType.AnyColor,
102+ CompositeType.Xor,
103+ SurfaceType.Any),
104+ new GraphicsPrimitiveProxy(owner, "XorFillPathANY",
105+ FillPath.methodSignature,
106+ FillPath.primTypeID,
107+ SurfaceType.AnyColor,
108+ CompositeType.Xor,
109+ SurfaceType.Any),
110+ new GraphicsPrimitiveProxy(owner, "XorFillSpansANY",
111+ FillSpans.methodSignature,
112+ FillSpans.primTypeID,
113+ SurfaceType.AnyColor,
114+ CompositeType.Xor,
115+ SurfaceType.Any),
116+ new GraphicsPrimitiveProxy(owner, "XorDrawLineANY",
117+ DrawLine.methodSignature,
118+ DrawLine.primTypeID,
119+ SurfaceType.AnyColor,
120+ CompositeType.Xor,
121+ SurfaceType.Any),
122+ new GraphicsPrimitiveProxy(owner, "XorDrawPolygonsANY",
123+ DrawPolygons.methodSignature,
124+ DrawPolygons.primTypeID,
125+ SurfaceType.AnyColor,
126+ CompositeType.Xor,
127+ SurfaceType.Any),
128+ new GraphicsPrimitiveProxy(owner, "XorDrawPathANY",
129+ DrawPath.methodSignature,
130+ DrawPath.primTypeID,
131+ SurfaceType.AnyColor,
132+ CompositeType.Xor,
133+ SurfaceType.Any),
134+ new GraphicsPrimitiveProxy(owner, "XorDrawRectANY",
135+ DrawRect.methodSignature,
136+ DrawRect.primTypeID,
137+ SurfaceType.AnyColor,
138+ CompositeType.Xor,
139+ SurfaceType.Any),
140+ new GraphicsPrimitiveProxy(owner, "XorDrawGlyphListANY",
141+ DrawGlyphList.methodSignature,
142+ DrawGlyphList.primTypeID,
143+ SurfaceType.AnyColor,
144+ CompositeType.Xor,
145+ SurfaceType.Any),
146+ new GraphicsPrimitiveProxy(owner, "XorDrawGlyphListAAANY",
147+ DrawGlyphListAA.methodSignature,
148+ DrawGlyphListAA.primTypeID,
149+ SurfaceType.AnyColor,
150+ CompositeType.Xor,
151+ SurfaceType.Any),
152+ };
153+ GraphicsPrimitiveMgr.register(primitives);
154+ }
155+
156+ static void doDrawPoly(SurfaceData sData, PixelWriter pw,
157+ int xPoints[], int yPoints[], int off, int nPoints,
158+ Region clip, int transx, int transy, boolean close)
159+ {
160+ int mx, my, x1, y1;
161+ int[] tmp = null;
162+
163+ if (nPoints <= 0) {
164+ return;
165+ }
166+ mx = x1 = xPoints[off] + transx;
167+ my = y1 = yPoints[off] + transy;
168+ while (--nPoints > 0) {
169+ ++off;
170+ int x2 = xPoints[off] + transx;
171+ int y2 = yPoints[off] + transy;
172+ tmp = GeneralRenderer.doDrawLine(sData, pw, tmp, clip,
173+ x1, y1, x2, y2);
174+ x1 = x2;
175+ y1 = y2;
176+ }
177+ if (close && (x1 != mx || y1 != my)) {
178+ tmp = GeneralRenderer.doDrawLine(sData, pw, tmp, clip,
179+ x1, y1, mx, my);
180+ }
181+ }
182+
183+ static void doSetRect(SurfaceData sData, PixelWriter pw,
184+ int x1, int y1, int x2, int y2) {
185+ WritableRaster dstRast =
186+ (WritableRaster) sData.getRaster(x1, y1, x2-x1, y2-y1);
187+ pw.setRaster(dstRast);
188+
189+ while (y1 < y2) {
190+ for (int x = x1; x < x2; x++) {
191+ pw.writePixel(x, y1);
192+ }
193+ y1++;
194+ }
195+ }
196+
197+ static int[] doDrawLine(SurfaceData sData, PixelWriter pw, int[] boundPts,
198+ Region clip,
199+ int origx1, int origy1, int origx2, int origy2)
200+ {
201+ if (boundPts == null) {
202+ boundPts = new int[8];
203+ }
204+ boundPts[0] = origx1;
205+ boundPts[1] = origy1;
206+ boundPts[2] = origx2;
207+ boundPts[3] = origy2;
208+ if (!adjustLine(boundPts,
209+ clip.getLoX(), clip.getLoY(),
210+ clip.getHiX(), clip.getHiY()))
211+ {
212+ return boundPts;
213+ }
214+ int x1 = boundPts[0];
215+ int y1 = boundPts[1];
216+ int x2 = boundPts[2];
217+ int y2 = boundPts[3];
218+
219+ WritableRaster dstRast = (WritableRaster)
220+ sData.getRaster(Math.min(x1, x2), Math.min(y1, y2),
221+ Math.abs(x1 - x2) + 1, Math.abs(y1 - y2) + 1);
222+ pw.setRaster(dstRast);
223+
224+ /* this could be made smaller, more elegant, more traditional. */
225+ if (x1 == x2) {
226+ if (y1 > y2) {
227+ do {
228+ pw.writePixel(x1, y1);
229+ y1--;
230+ } while (y1 >= y2);
231+ } else {
232+ do {
233+ pw.writePixel(x1, y1);
234+ y1++;
235+ } while (y1 <= y2);
236+ }
237+ } else if (y1 == y2) {
238+ if (x1 > x2) {
239+ do {
240+ pw.writePixel(x1, y1);
241+ x1--;
242+ } while (x1 >= x2);
243+ } else {
244+ do {
245+ pw.writePixel(x1, y1);
246+ x1++;
247+ } while (x1 <= x2);
248+ }
249+ } else {
250+ int dx = boundPts[4];
251+ int dy = boundPts[5];
252+ int ax = boundPts[6];
253+ int ay = boundPts[7];
254+ int steps;
255+ int bumpmajor;
256+ int bumpminor;
257+ int errminor;
258+ int errmajor;
259+ int error;
260+ boolean xmajor;
261+
262+ if (ax >= ay) {
263+ /* x is dominant */
264+ xmajor = true;
265+ errmajor = ay * 2;
266+ errminor = ax * 2;
267+ bumpmajor = (dx < 0) ? -1 : 1;
268+ bumpminor = (dy < 0) ? -1 : 1;
269+ ax = -ax; /* For clipping adjustment below */
270+ steps = x2 - x1;
271+ } else {
272+ /* y is dominant */
273+ xmajor = false;
274+ errmajor = ax * 2;
275+ errminor = ay * 2;
276+ bumpmajor = (dy < 0) ? -1 : 1;
277+ bumpminor = (dx < 0) ? -1 : 1;
278+ ay = -ay; /* For clipping adjustment below */
279+ steps = y2 - y1;
280+ }
281+ error = - (errminor / 2);
282+ if (y1 != origy1) {
283+ int ysteps = y1 - origy1;
284+ if (ysteps < 0) {
285+ ysteps = -ysteps;
286+ }
287+ error += ysteps * ax * 2;
288+ }
289+ if (x1 != origx1) {
290+ int xsteps = x1 - origx1;
291+ if (xsteps < 0) {
292+ xsteps = -xsteps;
293+ }
294+ error += xsteps * ay * 2;
295+ }
296+ if (steps < 0) {
297+ steps = -steps;
298+ }
299+ if (xmajor) {
300+ do {
301+ pw.writePixel(x1, y1);
302+ x1 += bumpmajor;
303+ error += errmajor;
304+ if (error >= 0) {
305+ y1 += bumpminor;
306+ error -= errminor;
307+ }
308+ } while (--steps >= 0);
309+ } else {
310+ do {
311+ pw.writePixel(x1, y1);
312+ y1 += bumpmajor;
313+ error += errmajor;
314+ if (error >= 0) {
315+ x1 += bumpminor;
316+ error -= errminor;
317+ }
318+ } while (--steps >= 0);
319+ }
320+ }
321+ return boundPts;
322+ }
323+
324+ public static void doDrawRect(PixelWriter pw,
325+ SunGraphics2D sg2d, SurfaceData sData,
326+ int x, int y, int w, int h)
327+ {
328+ if (w < 0 || h < 0) {
329+ return;
330+ }
331+ int x2 = Region.dimAdd(Region.dimAdd(x, w), 1);
332+ int y2 = Region.dimAdd(Region.dimAdd(y, h), 1);
333+ Region r = sg2d.getCompClip().getBoundsIntersectionXYXY(x, y, x2, y2);
334+ if (r.isEmpty()) {
335+ return;
336+ }
337+ int cx1 = r.getLoX();
338+ int cy1 = r.getLoY();
339+ int cx2 = r.getHiX();
340+ int cy2 = r.getHiY();
341+
342+ if (w < 2 || h < 2) {
343+ doSetRect(sData, pw, cx1, cy1, cx2, cy2);
344+ return;
345+ }
346+
347+
348+ if (cy1 == y) {
349+ doSetRect(sData, pw, cx1, cy1, cx2, cy1+1);
350+ }
351+ if (cx1 == x) {
352+ doSetRect(sData, pw, cx1, cy1+1, cx1+1, cy2-1);
353+ }
354+ if (cx2 == x2) {
355+ doSetRect(sData, pw, cx2-1, cy1+1, cx2, cy2-1);
356+ }
357+ if (cy2 == y2) {
358+ doSetRect(sData, pw, cx1, cy2-1, cx2, cy2);
359+ }
360+ }
361+
362+ /*
363+ * REMIND: For now this will field both AA and non-AA requests and
364+ * use a simple threshold to choose pixels if the supplied grey
365+ * bits are antialiased. We should really find a way to disable
366+ * AA text at a higher level or to have the GlyphList be able to
367+ * reset the glyphs to non-AA after construction.
368+ */
369+ static void doDrawGlyphList(SurfaceData sData, PixelWriter pw,
370+ GlyphList gl, Region clip)
371+ {
372+ int[] bounds = gl.getBounds();
373+ clip.clipBoxToBounds(bounds);
374+ int cx1 = bounds[0];
375+ int cy1 = bounds[1];
376+ int cx2 = bounds[2];
377+ int cy2 = bounds[3];
378+
379+ WritableRaster dstRast =
380+ (WritableRaster) sData.getRaster(cx1, cy1, cx2 - cx1, cy2 - cy1);
381+ pw.setRaster(dstRast);
382+
383+ int num = gl.getNumGlyphs();
384+ for (int i = 0; i < num; i++) {
385+ gl.setGlyphIndex(i);
386+ int metrics[] = gl.getMetrics();
387+ int gx1 = metrics[0];
388+ int gy1 = metrics[1];
389+ int w = metrics[2];
390+ int gx2 = gx1 + w;
391+ int gy2 = gy1 + metrics[3];
392+ int off = 0;
393+ if (gx1 < cx1) {
394+ off = cx1 - gx1;
395+ gx1 = cx1;
396+ }
397+ if (gy1 < cy1) {
398+ off += (cy1 - gy1) * w;
399+ gy1 = cy1;
400+ }
401+ if (gx2 > cx2) gx2 = cx2;
402+ if (gy2 > cy2) gy2 = cy2;
403+ if (gx2 > gx1 && gy2 > gy1) {
404+ byte alpha[] = gl.getGrayBits();
405+ w -= (gx2 - gx1);
406+ for (int y = gy1; y < gy2; y++) {
407+ for (int x = gx1; x < gx2; x++) {
408+ if (alpha[off++] < 0) {
409+ pw.writePixel(x, y);
410+ }
411+ }
412+ off += w;
413+ }
414+ }
415+ }
416+ }
417+
418+ static final int OUTCODE_TOP = 1;
419+ static final int OUTCODE_BOTTOM = 2;
420+ static final int OUTCODE_LEFT = 4;
421+ static final int OUTCODE_RIGHT = 8;
422+
423+ static int outcode(int x, int y, int xmin, int ymin, int xmax, int ymax) {
424+ int code;
425+ if (y < ymin) {
426+ code = OUTCODE_TOP;
427+ } else if (y > ymax) {
428+ code = OUTCODE_BOTTOM;
429+ } else {
430+ code = 0;
431+ }
432+ if (x < xmin) {
433+ code |= OUTCODE_LEFT;
434+ } else if (x > xmax) {
435+ code |= OUTCODE_RIGHT;
436+ }
437+ return code;
438+ }
439+
440+ public static boolean adjustLine(int [] boundPts,
441+ int cxmin, int cymin, int cx2, int cy2)
442+ {
443+ int cxmax = cx2 - 1;
444+ int cymax = cy2 - 1;
445+ int x1 = boundPts[0];
446+ int y1 = boundPts[1];
447+ int x2 = boundPts[2];
448+ int y2 = boundPts[3];
449+
450+ if ((cxmax < cxmin) || (cymax < cymin)) {
451+ return false;
452+ }
453+
454+ if (x1 == x2) {
455+ if (x1 < cxmin || x1 > cxmax) {
456+ return false;
457+ }
458+ if (y1 > y2) {
459+ int t = y1;
460+ y1 = y2;
461+ y2 = t;
462+ }
463+ if (y1 < cymin) {
464+ y1 = cymin;
465+ }
466+ if (y2 > cymax) {
467+ y2 = cymax;
468+ }
469+ if (y1 > y2) {
470+ return false;
471+ }
472+ boundPts[1] = y1;
473+ boundPts[3] = y2;
474+ } else if (y1 == y2) {
475+ if (y1 < cymin || y1 > cymax) {
476+ return false;
477+ }
478+ if (x1 > x2) {
479+ int t = x1;
480+ x1 = x2;
481+ x2 = t;
482+ }
483+ if (x1 < cxmin) {
484+ x1 = cxmin;
485+ }
486+ if (x2 > cxmax) {
487+ x2 = cxmax;
488+ }
489+ if (x1 > x2) {
490+ return false;
491+ }
492+ boundPts[0] = x1;
493+ boundPts[2] = x2;
494+ } else {
495+ /* REMIND: This could overflow... */
496+ int outcode1, outcode2;
497+ int dx = x2 - x1;
498+ int dy = y2 - y1;
499+ int ax = (dx < 0) ? -dx : dx;
500+ int ay = (dy < 0) ? -dy : dy;
501+ boolean xmajor = (ax >= ay);
502+
503+ outcode1 = outcode(x1, y1, cxmin, cymin, cxmax, cymax);
504+ outcode2 = outcode(x2, y2, cxmin, cymin, cxmax, cymax);
505+ while ((outcode1 | outcode2) != 0) {
506+ int xsteps, ysteps;
507+ if ((outcode1 & outcode2) != 0) {
508+ return false;
509+ }
510+ if (outcode1 != 0) {
511+ if (0 != (outcode1 & (OUTCODE_TOP | OUTCODE_BOTTOM))) {
512+ if (0 != (outcode1 & OUTCODE_TOP)) {
513+ y1 = cymin;
514+ } else {
515+ y1 = cymax;
516+ }
517+ ysteps = y1 - boundPts[1];
518+ if (ysteps < 0) {
519+ ysteps = -ysteps;
520+ }
521+ xsteps = 2 * ysteps * ax + ay;
522+ if (xmajor) {
523+ xsteps += ay - ax - 1;
524+ }
525+ xsteps = xsteps / (2 * ay);
526+ if (dx < 0) {
527+ xsteps = -xsteps;
528+ }
529+ x1 = boundPts[0] + xsteps;
530+ } else if (0 !=
531+ (outcode1 & (OUTCODE_LEFT | OUTCODE_RIGHT))) {
532+ if (0 != (outcode1 & OUTCODE_LEFT)) {
533+ x1 = cxmin;
534+ } else {
535+ x1 = cxmax;
536+ }
537+ xsteps = x1 - boundPts[0];
538+ if (xsteps < 0) {
539+ xsteps = -xsteps;
540+ }
541+ ysteps = 2 * xsteps * ay + ax;
542+ if (!xmajor) {
543+ ysteps += ax - ay - 1;
544+ }
545+ ysteps = ysteps / (2 * ax);
546+ if (dy < 0) {
547+ ysteps = -ysteps;
548+ }
549+ y1 = boundPts[1] + ysteps;
550+ }
551+ outcode1 = outcode(x1, y1, cxmin, cymin, cxmax, cymax);
552+ } else {
553+ if (0 != (outcode2 & (OUTCODE_TOP | OUTCODE_BOTTOM))) {
554+ if (0 != (outcode2 & OUTCODE_TOP)) {
555+ y2 = cymin;
556+ } else {
557+ y2 = cymax;
558+ }
559+ ysteps = y2 - boundPts[3];
560+ if (ysteps < 0) {
561+ ysteps = -ysteps;
562+ }
563+ xsteps = 2 * ysteps * ax + ay;
564+ if (xmajor) {
565+ xsteps += ay - ax;
566+ } else {
567+ xsteps -= 1;
568+ }
569+ xsteps = xsteps / (2 * ay);
570+ if (dx > 0) {
571+ xsteps = -xsteps;
572+ }
573+ x2 = boundPts[2] + xsteps;
574+ } else if (0 !=
575+ (outcode2 & (OUTCODE_LEFT | OUTCODE_RIGHT))) {
576+ if (0 != (outcode2 & OUTCODE_LEFT)) {
577+ x2 = cxmin;
578+ } else {
579+ x2 = cxmax;
580+ }
581+ xsteps = x2 - boundPts[2];
582+ if (xsteps < 0) {
583+ xsteps = -xsteps;
584+ }
585+ ysteps = 2 * xsteps * ay + ax;
586+ if (xmajor) {
587+ ysteps -= 1;
588+ } else {
589+ ysteps += ax - ay;
590+ }
591+ ysteps = ysteps / (2 * ax);
592+ if (dy > 0) {
593+ ysteps = -ysteps;
594+ }
595+ y2 = boundPts[3] + ysteps;
596+ }
597+ outcode2 = outcode(x2, y2, cxmin, cymin, cxmax, cymax);
598+ }
599+ }
600+ boundPts[0] = x1;
601+ boundPts[1] = y1;
602+ boundPts[2] = x2;
603+ boundPts[3] = y2;
604+ boundPts[4] = dx;
605+ boundPts[5] = dy;
606+ boundPts[6] = ax;
607+ boundPts[7] = ay;
608+ }
609+ return true;
610+ }
611+
612+ static PixelWriter createSolidPixelWriter(SunGraphics2D sg2d,
613+ SurfaceData sData)
614+ {
615+ ColorModel dstCM = sData.getColorModel();
616+ Object srcPixel = dstCM.getDataElements(sg2d.eargb, null);
617+
618+ return new SolidPixelWriter(srcPixel);
619+ }
620+
621+ static PixelWriter createXorPixelWriter(SunGraphics2D sg2d,
622+ SurfaceData sData)
623+ {
624+ ColorModel dstCM = sData.getColorModel();
625+
626+ Object srcPixel = dstCM.getDataElements(sg2d.eargb, null);
627+
628+ XORComposite comp = (XORComposite)sg2d.getComposite();
629+ int xorrgb = comp.getXorColor().getRGB();
630+ Object xorPixel = dstCM.getDataElements(xorrgb, null);
631+
632+ switch (dstCM.getTransferType()) {
633+ case DataBuffer.TYPE_BYTE:
634+ return new XorPixelWriter.ByteData(srcPixel, xorPixel);
635+ case DataBuffer.TYPE_SHORT:
636+ case DataBuffer.TYPE_USHORT:
637+ return new XorPixelWriter.ShortData(srcPixel, xorPixel);
638+ case DataBuffer.TYPE_INT:
639+ return new XorPixelWriter.IntData(srcPixel, xorPixel);
640+ case DataBuffer.TYPE_FLOAT:
641+ return new XorPixelWriter.FloatData(srcPixel, xorPixel);
642+ case DataBuffer.TYPE_DOUBLE:
643+ return new XorPixelWriter.DoubleData(srcPixel, xorPixel);
644+ default:
645+ throw new InternalError("Unsupported XOR pixel type");
646+ }
647+ }
648+}
649+
650+class SetFillRectANY extends FillRect {
651+ SetFillRectANY() {
652+ super(SurfaceType.AnyColor,
653+ CompositeType.SrcNoEa,
654+ SurfaceType.Any);
655+ }
656+
657+ public void FillRect(SunGraphics2D sg2d, SurfaceData sData,
658+ int x, int y, int w, int h)
659+ {
660+ PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);
661+
662+ Region r = sg2d.getCompClip().getBoundsIntersectionXYWH(x, y, w, h);
663+
664+ GeneralRenderer.doSetRect(sData, pw,
665+ r.getLoX(), r.getLoY(),
666+ r.getHiX(), r.getHiY());
667+ }
668+}
669+
670+class PixelWriterDrawHandler extends ProcessPath.DrawHandler {
671+ PixelWriter pw;
672+ SurfaceData sData;
673+ Region clip;
674+
675+ public PixelWriterDrawHandler(SurfaceData sData, PixelWriter pw,
676+ Region clip, int strokeHint) {
677+ super(clip.getLoX(), clip.getLoY(),
678+ clip.getHiX(), clip.getHiY(),
679+ strokeHint);
680+ this.sData = sData;
681+ this.pw = pw;
682+ this.clip = clip;
683+ }
684+
685+ public void drawLine(int x0, int y0, int x1, int y1) {
686+ GeneralRenderer.doDrawLine(sData, pw, null, clip,
687+ x0, y0, x1, y1);
688+ }
689+
690+ public void drawPixel(int x0, int y0) {
691+ GeneralRenderer.doSetRect(sData, pw, x0, y0, x0 + 1, y0 + 1);
692+ }
693+
694+ public void drawScanline(int x0, int x1, int y0) {
695+ GeneralRenderer.doSetRect(sData, pw, x0, y0, x1 + 1, y0 + 1);
696+ }
697+}
698+
699+class SetFillPathANY extends FillPath {
700+ SetFillPathANY() {
701+ super(SurfaceType.AnyColor, CompositeType.SrcNoEa,
702+ SurfaceType.Any);
703+ }
704+
705+ public void FillPath(SunGraphics2D sg2d, SurfaceData sData,
706+ int transx, int transy,
707+ Path2D.Float p2df)
708+ {
709+ PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);
710+ ProcessPath.fillPath(
711+ new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(),
712+ sg2d.strokeHint),
713+ p2df, transx, transy);
714+ }
715+}
716+
717+class SetFillSpansANY extends FillSpans {
718+ SetFillSpansANY() {
719+ super(SurfaceType.AnyColor,
720+ CompositeType.SrcNoEa,
721+ SurfaceType.Any);
722+ }
723+
724+ public void FillSpans(SunGraphics2D sg2d, SurfaceData sData,
725+ SpanIterator si)
726+ {
727+ PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);
728+
729+ int span[] = new int[4];
730+ while (si.nextSpan(span)) {
731+ GeneralRenderer.doSetRect(sData, pw,
732+ span[0], span[1], span[2], span[3]);
733+ }
734+ }
735+}
736+
737+class SetDrawLineANY extends DrawLine {
738+ SetDrawLineANY() {
739+ super(SurfaceType.AnyColor,
740+ CompositeType.SrcNoEa,
741+ SurfaceType.Any);
742+ }
743+
744+ public void DrawLine(SunGraphics2D sg2d, SurfaceData sData,
745+ int x1, int y1, int x2, int y2)
746+ {
747+ PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);
748+
749+ if (y1 >= y2) {
750+ GeneralRenderer.doDrawLine(sData, pw, null,
751+ sg2d.getCompClip(),
752+ x2, y2, x1, y1);
753+ } else {
754+ GeneralRenderer.doDrawLine(sData, pw, null,
755+ sg2d.getCompClip(),
756+ x1, y1, x2, y2);
757+ }
758+ }
759+}
760+
761+class SetDrawPolygonsANY extends DrawPolygons {
762+ SetDrawPolygonsANY() {
763+ super(SurfaceType.AnyColor,
764+ CompositeType.SrcNoEa,
765+ SurfaceType.Any);
766+ }
767+
768+ public void DrawPolygons(SunGraphics2D sg2d, SurfaceData sData,
769+ int xPoints[], int yPoints[],
770+ int nPoints[], int numPolys,
771+ int transx, int transy,
772+ boolean close)
773+ {
774+ PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);
775+
776+ int off = 0;
777+ Region clip = sg2d.getCompClip();
778+ for (int i = 0; i < numPolys; i++) {
779+ int numpts = nPoints[i];
780+ GeneralRenderer.doDrawPoly(sData, pw,
781+ xPoints, yPoints, off, numpts,
782+ clip, transx, transy, close);
783+ off += numpts;
784+ }
785+ }
786+}
787+
788+class SetDrawPathANY extends DrawPath {
789+ SetDrawPathANY() {
790+ super(SurfaceType.AnyColor,
791+ CompositeType.SrcNoEa,
792+ SurfaceType.Any);
793+ }
794+
795+ public void DrawPath(SunGraphics2D sg2d, SurfaceData sData,
796+ int transx, int transy,
797+ Path2D.Float p2df)
798+ {
799+ PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);
800+ ProcessPath.drawPath(
801+ new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(),
802+ sg2d.strokeHint),
803+ p2df, transx, transy
804+ );
805+ }
806+}
807+
808+class SetDrawRectANY extends DrawRect {
809+ SetDrawRectANY() {
810+ super(SurfaceType.AnyColor,
811+ CompositeType.SrcNoEa,
812+ SurfaceType.Any);
813+ }
814+
815+ public void DrawRect(SunGraphics2D sg2d, SurfaceData sData,
816+ int x, int y, int w, int h)
817+ {
818+ PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);
819+
820+ GeneralRenderer.doDrawRect(pw, sg2d, sData, x, y, w, h);
821+ }
822+}
823+
824+class XorFillRectANY extends FillRect {
825+ XorFillRectANY() {
826+ super(SurfaceType.AnyColor,
827+ CompositeType.Xor,
828+ SurfaceType.Any);
829+ }
830+
831+ public void FillRect(SunGraphics2D sg2d, SurfaceData sData,
832+ int x, int y, int w, int h)
833+ {
834+ PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);
835+
836+ Region r = sg2d.getCompClip().getBoundsIntersectionXYWH(x, y, w, h);
837+
838+ GeneralRenderer.doSetRect(sData, pw,
839+ r.getLoX(), r.getLoY(),
840+ r.getHiX(), r.getHiY());
841+ }
842+}
843+
844+class XorFillPathANY extends FillPath {
845+ XorFillPathANY() {
846+ super(SurfaceType.AnyColor, CompositeType.Xor,
847+ SurfaceType.Any);
848+ }
849+
850+ public void FillPath(SunGraphics2D sg2d, SurfaceData sData,
851+ int transx, int transy,
852+ Path2D.Float p2df)
853+ {
854+ PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);
855+ ProcessPath.fillPath(
856+ new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(),
857+ sg2d.strokeHint),
858+ p2df, transx, transy);
859+ }
860+}
861+
862+class XorFillSpansANY extends FillSpans {
863+ XorFillSpansANY() {
864+ super(SurfaceType.AnyColor,
865+ CompositeType.Xor,
866+ SurfaceType.Any);
867+ }
868+
869+ public void FillSpans(SunGraphics2D sg2d, SurfaceData sData,
870+ SpanIterator si)
871+ {
872+ PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);
873+
874+ int span[] = new int[4];
875+ while (si.nextSpan(span)) {
876+ GeneralRenderer.doSetRect(sData, pw,
877+ span[0], span[1], span[2], span[3]);
878+ }
879+ }
880+}
881+
882+class XorDrawLineANY extends DrawLine {
883+ XorDrawLineANY() {
884+ super(SurfaceType.AnyColor,
885+ CompositeType.Xor,
886+ SurfaceType.Any);
887+ }
888+
889+ public void DrawLine(SunGraphics2D sg2d, SurfaceData sData,
890+ int x1, int y1, int x2, int y2)
891+ {
892+ PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);
893+
894+ if (y1 >= y2) {
895+ GeneralRenderer.doDrawLine(sData, pw, null,
896+ sg2d.getCompClip(),
897+ x2, y2, x1, y1);
898+ } else {
899+ GeneralRenderer.doDrawLine(sData, pw, null,
900+ sg2d.getCompClip(),
901+ x1, y1, x2, y2);
902+ }
903+ }
904+}
905+
906+class XorDrawPolygonsANY extends DrawPolygons {
907+ XorDrawPolygonsANY() {
908+ super(SurfaceType.AnyColor,
909+ CompositeType.Xor,
910+ SurfaceType.Any);
911+ }
912+
913+ public void DrawPolygons(SunGraphics2D sg2d, SurfaceData sData,
914+ int xPoints[], int yPoints[],
915+ int nPoints[], int numPolys,
916+ int transx, int transy,
917+ boolean close)
918+ {
919+ PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);
920+
921+ int off = 0;
922+ Region clip = sg2d.getCompClip();
923+ for (int i = 0; i < numPolys; i++) {
924+ int numpts = nPoints[i];
925+ GeneralRenderer.doDrawPoly(sData, pw,
926+ xPoints, yPoints, off, numpts,
927+ clip, transx, transy, close);
928+ off += numpts;
929+ }
930+ }
931+}
932+
933+class XorDrawPathANY extends DrawPath {
934+ XorDrawPathANY() {
935+ super(SurfaceType.AnyColor,
936+ CompositeType.Xor,
937+ SurfaceType.Any);
938+ }
939+
940+ public void DrawPath(SunGraphics2D sg2d, SurfaceData sData,
941+ int transx, int transy, Path2D.Float p2df)
942+ {
943+ PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);
944+ ProcessPath.drawPath(
945+ new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(),
946+ sg2d.strokeHint),
947+ p2df, transx, transy
948+ );
949+ }
950+}
951+
952+class XorDrawRectANY extends DrawRect {
953+ XorDrawRectANY() {
954+ super(SurfaceType.AnyColor,
955+ CompositeType.Xor,
956+ SurfaceType.Any);
957+ }
958+
959+ public void DrawRect(SunGraphics2D sg2d, SurfaceData sData,
960+ int x, int y, int w, int h)
961+ {
962+ PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);
963+
964+ GeneralRenderer.doDrawRect(pw, sg2d, sData, x, y, w, h);
965+ }
966+}
967+
968+class XorDrawGlyphListANY extends DrawGlyphList {
969+ XorDrawGlyphListANY() {
970+ super(SurfaceType.AnyColor,
971+ CompositeType.Xor,
972+ SurfaceType.Any);
973+ }
974+
975+ public void DrawGlyphList(SunGraphics2D sg2d, SurfaceData sData,
976+ GlyphList gl)
977+ {
978+ PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);
979+ GeneralRenderer.doDrawGlyphList(sData, pw, gl, sg2d.getCompClip());
980+ }
981+}
982+
983+class XorDrawGlyphListAAANY extends DrawGlyphListAA {
984+ XorDrawGlyphListAAANY() {
985+ super(SurfaceType.AnyColor,
986+ CompositeType.Xor,
987+ SurfaceType.Any);
988+ }
989+
990+ public void DrawGlyphListAA(SunGraphics2D sg2d, SurfaceData sData,
991+ GlyphList gl)
992+ {
993+ PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);
994+ GeneralRenderer.doDrawGlyphList(sData, pw, gl, sg2d.getCompClip());
995+ }
996+}
997+
998+abstract class PixelWriter {
999+ protected WritableRaster dstRast;
1000+
1001+ public void setRaster(WritableRaster dstRast) {
1002+ this.dstRast = dstRast;
1003+ }
1004+
1005+ public abstract void writePixel(int x, int y);
1006+}
1007+
1008+class SolidPixelWriter extends PixelWriter {
1009+ protected Object srcData;
1010+
1011+ SolidPixelWriter(Object srcPixel) {
1012+ this.srcData = srcPixel;
1013+ }
1014+
1015+ public void writePixel(int x, int y) {
1016+ dstRast.setDataElements(x, y, srcData);
1017+ }
1018+}
1019+
1020+abstract class XorPixelWriter extends PixelWriter {
1021+ protected ColorModel dstCM;
1022+
1023+ public void writePixel(int x, int y) {
1024+ Object dstPixel = dstRast.getDataElements(x, y, null);
1025+ xorPixel(dstPixel);
1026+ dstRast.setDataElements(x, y, dstPixel);
1027+ }
1028+
1029+ protected abstract void xorPixel(Object pixData);
1030+
1031+ public static class ByteData extends XorPixelWriter {
1032+ byte[] xorData;
1033+
1034+ ByteData(Object srcPixel, Object xorPixel) {
1035+ this.xorData = (byte[]) srcPixel;
1036+ xorPixel(xorPixel);
1037+ this.xorData = (byte[]) xorPixel;
1038+ }
1039+
1040+ protected void xorPixel(Object pixData) {
1041+ byte[] dstData = (byte[]) pixData;
1042+ for (int i = 0; i < dstData.length; i++) {
1043+ dstData[i] ^= xorData[i];
1044+ }
1045+ }
1046+ }
1047+
1048+ public static class ShortData extends XorPixelWriter {
1049+ short[] xorData;
1050+
1051+ ShortData(Object srcPixel, Object xorPixel) {
1052+ this.xorData = (short[]) srcPixel;
1053+ xorPixel(xorPixel);
1054+ this.xorData = (short[]) xorPixel;
1055+ }
1056+
1057+ protected void xorPixel(Object pixData) {
1058+ short[] dstData = (short[]) pixData;
1059+ for (int i = 0; i < dstData.length; i++) {
1060+ dstData[i] ^= xorData[i];
1061+ }
1062+ }
1063+ }
1064+
1065+ public static class IntData extends XorPixelWriter {
1066+ int[] xorData;
1067+
1068+ IntData(Object srcPixel, Object xorPixel) {
1069+ this.xorData = (int[]) srcPixel;
1070+ xorPixel(xorPixel);
1071+ this.xorData = (int[]) xorPixel;
1072+ }
1073+
1074+ protected void xorPixel(Object pixData) {
1075+ int[] dstData = (int[]) pixData;
1076+ for (int i = 0; i < dstData.length; i++) {
1077+ dstData[i] ^= xorData[i];
1078+ }
1079+ }
1080+ }
1081+
1082+ public static class FloatData extends XorPixelWriter {
1083+ int[] xorData;
1084+
1085+ FloatData(Object srcPixel, Object xorPixel) {
1086+ float[] srcData = (float[]) srcPixel;
1087+ float[] xorData = (float[]) xorPixel;
1088+ this.xorData = new int[srcData.length];
1089+ for (int i = 0; i < srcData.length; i++) {
1090+ this.xorData[i] = (Float.floatToIntBits(srcData[i]) ^
1091+ Float.floatToIntBits(xorData[i]));
1092+ }
1093+ }
1094+
1095+ protected void xorPixel(Object pixData) {
1096+ float[] dstData = (float[]) pixData;
1097+ for (int i = 0; i < dstData.length; i++) {
1098+ int v = Float.floatToIntBits(dstData[i]) ^ xorData[i];
1099+ dstData[i] = Float.intBitsToFloat(v);
1100+ }
1101+ }
1102+ }
1103+
1104+ public static class DoubleData extends XorPixelWriter {
1105+ long[] xorData;
1106+
1107+ DoubleData(Object srcPixel, Object xorPixel) {
1108+ double[] srcData = (double[]) srcPixel;
1109+ double[] xorData = (double[]) xorPixel;
1110+ this.xorData = new long[srcData.length];
1111+ for (int i = 0; i < srcData.length; i++) {
1112+ this.xorData[i] = (Double.doubleToLongBits(srcData[i]) ^
1113+ Double.doubleToLongBits(xorData[i]));
1114+ }
1115+ }
1116+
1117+ protected void xorPixel(Object pixData) {
1118+ double[] dstData = (double[]) pixData;
1119+ for (int i = 0; i < dstData.length; i++) {
1120+ long v = Double.doubleToLongBits(dstData[i]) ^ xorData[i];
1121+ dstData[i] = Double.longBitsToDouble(v);
1122+ }
1123+ }
1124+ }
1125+}
java/pkg/sun/java2d/loops/GraphicsPrimitive$1.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/GraphicsPrimitive$GeneralBinaryOp.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/GraphicsPrimitive$GeneralUnaryOp.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/GraphicsPrimitive$TraceReporter$1.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/GraphicsPrimitive$TraceReporter.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/GraphicsPrimitive.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/GraphicsPrimitive.java+623−0
@@ -0,0 +1,623 @@
1+/*
2+ * Copyright (c) 1997, 2010, 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+
26+/*
27+ * @author Charlton Innovations, Inc.
28+ */
29+
30+package sun.java2d.loops;
31+
32+import java.awt.image.BufferedImage;
33+import java.awt.AlphaComposite;
34+import java.awt.Rectangle;
35+import sun.awt.image.BufImgSurfaceData;
36+import sun.java2d.SurfaceData;
37+import sun.java2d.pipe.Region;
38+import java.lang.reflect.Field;
39+import java.util.StringTokenizer;
40+import java.util.Iterator;
41+import java.util.HashMap;
42+import java.util.Map;
43+import java.io.PrintStream;
44+import java.io.OutputStream;
45+import java.io.FileOutputStream;
46+import java.io.FileNotFoundException;
47+import java.security.AccessController;
48+import java.security.PrivilegedAction;
49+import sun.security.action.GetPropertyAction;
50+
51+/**
52+ * defines interface for primitives which can be placed into
53+ * the graphic component manager framework
54+ */
55+public abstract class GraphicsPrimitive {
56+
57+ protected static interface GeneralBinaryOp {
58+ /**
59+ * This method allows the setupGeneralBinaryOp method to set
60+ * the converters into the General version of the Primitive.
61+ */
62+ public void setPrimitives(Blit srcconverter,
63+ Blit dstconverter,
64+ GraphicsPrimitive genericop,
65+ Blit resconverter);
66+
67+ /**
68+ * These 4 methods are implemented automatically for any
69+ * GraphicsPrimitive. They are used by setupGeneralBinaryOp
70+ * to retrieve the information needed to find the right
71+ * converter primitives.
72+ */
73+ public SurfaceType getSourceType();
74+ public CompositeType getCompositeType();
75+ public SurfaceType getDestType();
76+ public String getSignature();
77+ public int getPrimTypeID();
78+ }
79+
80+ protected static interface GeneralUnaryOp {
81+ /**
82+ * This method allows the setupGeneralUnaryOp method to set
83+ * the converters into the General version of the Primitive.
84+ */
85+ public void setPrimitives(Blit dstconverter,
86+ GraphicsPrimitive genericop,
87+ Blit resconverter);
88+
89+ /**
90+ * These 3 methods are implemented automatically for any
91+ * GraphicsPrimitive. They are used by setupGeneralUnaryOp
92+ * to retrieve the information needed to find the right
93+ * converter primitives.
94+ */
95+ public CompositeType getCompositeType();
96+ public SurfaceType getDestType();
97+ public String getSignature();
98+ public int getPrimTypeID();
99+ }
100+
101+ /**
102+ * INSTANCE DATA MEMBERS DESCRIBING CHARACTERISTICS OF THIS PRIMITIVE
103+ **/
104+
105+ // Making these be instance data members (instead of virtual methods
106+ // overridden by subclasses) is actually cheaper, since each class
107+ // is a singleton. As instance data members with final accessors,
108+ // accesses can be inlined.
109+ private String methodSignature;
110+ private int uniqueID;
111+ private static int unusedPrimID = 1;
112+
113+ private SurfaceType sourceType;
114+ private CompositeType compositeType;
115+ private SurfaceType destType;
116+
117+ private long pNativePrim; // Native blit loop info
118+
119+ public synchronized static final int makePrimTypeID() {
120+ if (unusedPrimID > 255) {
121+ throw new InternalError("primitive id overflow");
122+ }
123+ return unusedPrimID++;
124+ }
125+
126+ public synchronized static final int makeUniqueID(int primTypeID,
127+ SurfaceType src,
128+ CompositeType cmp,
129+ SurfaceType dst)
130+ {
131+ return (primTypeID << 24) |
132+ (dst.getUniqueID() << 16) |
133+ (cmp.getUniqueID() << 8) |
134+ (src.getUniqueID());
135+ }
136+
137+ /**
138+ * Create a new GraphicsPrimitive with all of the required
139+ * descriptive information.
140+ */
141+ protected GraphicsPrimitive(String methodSignature,
142+ int primTypeID,
143+ SurfaceType sourceType,
144+ CompositeType compositeType,
145+ SurfaceType destType)
146+ {
147+ this.methodSignature = methodSignature;
148+ this.sourceType = sourceType;
149+ this.compositeType = compositeType;
150+ this.destType = destType;
151+
152+ if(sourceType == null || compositeType == null || destType == null) {
153+ this.uniqueID = primTypeID << 24;
154+ } else {
155+ this.uniqueID = GraphicsPrimitive.makeUniqueID(primTypeID,
156+ sourceType,
157+ compositeType,
158+ destType);
159+ }
160+ }
161+
162+ /**
163+ * Create a new GraphicsPrimitive for native invocation
164+ * with all of the required descriptive information.
165+ */
166+ protected GraphicsPrimitive(long pNativePrim,
167+ String methodSignature,
168+ int primTypeID,
169+ SurfaceType sourceType,
170+ CompositeType compositeType,
171+ SurfaceType destType)
172+ {
173+ this.pNativePrim = pNativePrim;
174+ this.methodSignature = methodSignature;
175+ this.sourceType = sourceType;
176+ this.compositeType = compositeType;
177+ this.destType = destType;
178+
179+ if(sourceType == null || compositeType == null || destType == null) {
180+ this.uniqueID = primTypeID << 24;
181+ } else {
182+ this.uniqueID = GraphicsPrimitive.makeUniqueID(primTypeID,
183+ sourceType,
184+ compositeType,
185+ destType);
186+ }
187+ }
188+
189+ /**
190+ * METHODS TO DESCRIBE THE SURFACES PRIMITIVES
191+ * CAN OPERATE ON AND THE FUNCTIONALITY THEY IMPLEMENT
192+ **/
193+
194+ /**
195+ * Gets instance ID of this graphics primitive.
196+ *
197+ * Instance ID is comprised of four distinct ids (ORed together)
198+ * that uniquely identify each instance of a GraphicsPrimitive
199+ * object. The four ids making up instance ID are:
200+ * 1. primitive id - identifier shared by all primitives of the
201+ * same type (eg. all Blits have the same primitive id)
202+ * 2. sourcetype id - identifies source surface type
203+ * 3. desttype id - identifies destination surface type
204+ * 4. compositetype id - identifies composite used
205+ *
206+ * @return instance ID
207+ */
208+ public final int getUniqueID() {
209+ return uniqueID;
210+ }
211+
212+ /**
213+ */
214+ public final String getSignature() {
215+ return methodSignature;
216+ }
217+
218+ /**
219+ * Gets unique id for this GraphicsPrimitive type.
220+ *
221+ * This id is used to identify the TYPE of primitive (Blit vs. BlitBg)
222+ * as opposed to INSTANCE of primitive.
223+ *
224+ * @return primitive ID
225+ */
226+ public final int getPrimTypeID() {
227+ return uniqueID >>> 24;
228+ }
229+
230+ /**
231+ */
232+ public final long getNativePrim() {
233+ return pNativePrim;
234+ }
235+
236+ /**
237+ */
238+ public final SurfaceType getSourceType() {
239+ return sourceType;
240+ }
241+
242+ /**
243+ */
244+ public final CompositeType getCompositeType() {
245+ return compositeType;
246+ }
247+
248+ /**
249+ */
250+ public final SurfaceType getDestType() {
251+ return destType;
252+ }
253+
254+ /**
255+ * Return true if this primitive can be used for the given signature
256+ * surfaces, and composite.
257+ *
258+ * @param signature The signature of the given operation. Must be
259+ * == (not just .equals) the signature string given by the
260+ * abstract class that declares the operation.
261+ * @param srctype The surface type for the source of the operation
262+ * @param comptype The composite type for the operation
263+ * @param dsttype The surface type for the destination of the operation
264+ */
265+ public final boolean satisfies(String signature,
266+ SurfaceType srctype,
267+ CompositeType comptype,
268+ SurfaceType dsttype)
269+ {
270+ if (signature != methodSignature) {
271+ return false;
272+ }
273+ while (true) {
274+ if (srctype == null) {
275+ return false;
276+ }
277+ if (srctype.equals(sourceType)) {
278+ break;
279+ }
280+ srctype = srctype.getSuperType();
281+ }
282+ while (true) {
283+ if (comptype == null) {
284+ return false;
285+ }
286+ if (comptype.equals(compositeType)) {
287+ break;
288+ }
289+ comptype = comptype.getSuperType();
290+ }
291+ while (true) {
292+ if (dsttype == null) {
293+ return false;
294+ }
295+ if (dsttype.equals(destType)) {
296+ break;
297+ }
298+ dsttype = dsttype.getSuperType();
299+ }
300+ return true;
301+ }
302+
303+ //
304+ // A version of satisfies used for regression testing
305+ //
306+ final boolean satisfiesSameAs(GraphicsPrimitive other) {
307+ return (methodSignature == other.methodSignature &&
308+ sourceType.equals(other.sourceType) &&
309+ compositeType.equals(other.compositeType) &&
310+ destType.equals(other.destType));
311+ }
312+
313+ public abstract GraphicsPrimitive makePrimitive(SurfaceType srctype,
314+ CompositeType comptype,
315+ SurfaceType dsttype);
316+
317+ public abstract GraphicsPrimitive traceWrap();
318+
319+ static HashMap traceMap;
320+
321+ public static int traceflags;
322+ public static String tracefile;
323+ public static PrintStream traceout;
324+
325+ public static final int TRACELOG = 1;
326+ public static final int TRACETIMESTAMP = 2;
327+ public static final int TRACECOUNTS = 4;
328+
329+ static {
330+ GetPropertyAction gpa = new GetPropertyAction("sun.java2d.trace");
331+ String trace = (String)AccessController.doPrivileged(gpa);
332+ if (trace != null) {
333+ boolean verbose = false;
334+ int traceflags = 0;
335+ StringTokenizer st = new StringTokenizer(trace, ",");
336+ while (st.hasMoreTokens()) {
337+ String tok = st.nextToken();
338+ if (tok.equalsIgnoreCase("count")) {
339+ traceflags |= GraphicsPrimitive.TRACECOUNTS;
340+ } else if (tok.equalsIgnoreCase("log")) {
341+ traceflags |= GraphicsPrimitive.TRACELOG;
342+ } else if (tok.equalsIgnoreCase("timestamp")) {
343+ traceflags |= GraphicsPrimitive.TRACETIMESTAMP;
344+ } else if (tok.equalsIgnoreCase("verbose")) {
345+ verbose = true;
346+ } else if (tok.regionMatches(true, 0, "out:", 0, 4)) {
347+ tracefile = tok.substring(4);
348+ } else {
349+ if (!tok.equalsIgnoreCase("help")) {
350+ System.err.println("unrecognized token: "+tok);
351+ }
352+ System.err.println("usage: -Dsun.java2d.trace="+
353+ "[log[,timestamp]],[count],"+
354+ "[out:<filename>],[help],[verbose]");
355+ }
356+ }
357+ if (verbose) {
358+ System.err.print("GraphicsPrimitive logging ");
359+ if ((traceflags & GraphicsPrimitive.TRACELOG) != 0) {
360+ System.err.println("enabled");
361+ System.err.print("GraphicsPrimitive timetamps ");
362+ if ((traceflags & GraphicsPrimitive.TRACETIMESTAMP) != 0) {
363+ System.err.println("enabled");
364+ } else {
365+ System.err.println("disabled");
366+ }
367+ } else {
368+ System.err.println("[and timestamps] disabled");
369+ }
370+ System.err.print("GraphicsPrimitive invocation counts ");
371+ if ((traceflags & GraphicsPrimitive.TRACECOUNTS) != 0) {
372+ System.err.println("enabled");
373+ } else {
374+ System.err.println("disabled");
375+ }
376+ System.err.print("GraphicsPrimitive trace output to ");
377+ if (tracefile == null) {
378+ System.err.println("System.err");
379+ } else {
380+ System.err.println("file '"+tracefile+"'");
381+ }
382+ }
383+ GraphicsPrimitive.traceflags = traceflags;
384+ }
385+ }
386+
387+ public static boolean tracingEnabled() {
388+ return (traceflags != 0);
389+ }
390+
391+ private static PrintStream getTraceOutputFile() {
392+ if (traceout == null) {
393+ if (tracefile != null) {
394+ Object o =
395+ AccessController.doPrivileged(new PrivilegedAction() {
396+ public Object run() {
397+ try {
398+ return new FileOutputStream(tracefile);
399+ } catch (FileNotFoundException e) {
400+ return null;
401+ }
402+ }
403+ });
404+ if (o != null) {
405+ traceout = new PrintStream((OutputStream) o);
406+ } else {
407+ traceout = System.err;
408+ }
409+ } else {
410+ traceout = System.err;
411+ }
412+ }
413+ return traceout;
414+ }
415+
416+ public static class TraceReporter extends Thread {
417+ public static void setShutdownHook() {
418+ AccessController.doPrivileged(new PrivilegedAction() {
419+ public Object run() {
420+ TraceReporter t = new TraceReporter();
421+ t.setContextClassLoader(null);
422+ Runtime.getRuntime().addShutdownHook(t);
423+ return null;
424+ }
425+ });
426+ }
427+
428+ public void run() {
429+ PrintStream ps = getTraceOutputFile();
430+ Iterator iterator = traceMap.entrySet().iterator();
431+ long total = 0;
432+ int numprims = 0;
433+ while (iterator.hasNext()) {
434+ Map.Entry me = (Map.Entry) iterator.next();
435+ Object prim = me.getKey();
436+ int[] count = (int[]) me.getValue();
437+ if (count[0] == 1) {
438+ ps.print("1 call to ");
439+ } else {
440+ ps.print(count[0]+" calls to ");
441+ }
442+ ps.println(prim);
443+ numprims++;
444+ total += count[0];
445+ }
446+ if (numprims == 0) {
447+ ps.println("No graphics primitives executed");
448+ } else if (numprims > 1) {
449+ ps.println(total+" total calls to "+
450+ numprims+" different primitives");
451+ }
452+ }
453+ }
454+
455+ public synchronized static void tracePrimitive(Object prim) {
456+ if ((traceflags & TRACECOUNTS) != 0) {
457+ if (traceMap == null) {
458+ traceMap = new HashMap();
459+ TraceReporter.setShutdownHook();
460+ }
461+ Object o = traceMap.get(prim);
462+ if (o == null) {
463+ o = new int[1];
464+ traceMap.put(prim, o);
465+ }
466+ ((int[]) o)[0]++;
467+ }
468+ if ((traceflags & TRACELOG) != 0) {
469+ PrintStream ps = getTraceOutputFile();
470+ if ((traceflags & TRACETIMESTAMP) != 0) {
471+ ps.print(System.currentTimeMillis()+": ");
472+ }
473+ ps.println(prim);
474+ }
475+ }
476+
477+ protected void setupGeneralBinaryOp(GeneralBinaryOp gbo) {
478+ int primID = gbo.getPrimTypeID();
479+ String methodSignature = gbo.getSignature();
480+ SurfaceType srctype = gbo.getSourceType();
481+ CompositeType comptype = gbo.getCompositeType();
482+ SurfaceType dsttype = gbo.getDestType();
483+ Blit convertsrc, convertdst, convertres;
484+ GraphicsPrimitive performop;
485+
486+ convertsrc = createConverter(srctype, SurfaceType.IntArgb);
487+ performop = GraphicsPrimitiveMgr.locatePrim(primID,
488+ SurfaceType.IntArgb,
489+ comptype, dsttype);
490+ if (performop != null) {
491+ convertdst = null;
492+ convertres = null;
493+ } else {
494+ performop = getGeneralOp(primID, comptype);
495+ if (performop == null) {
496+ throw new InternalError("Cannot construct general op for "+
497+ methodSignature+" "+comptype);
498+ }
499+ convertdst = createConverter(dsttype, SurfaceType.IntArgb);
500+ convertres = createConverter(SurfaceType.IntArgb, dsttype);
501+ }
502+
503+ gbo.setPrimitives(convertsrc, convertdst, performop, convertres);
504+ }
505+
506+ protected void setupGeneralUnaryOp(GeneralUnaryOp guo) {
507+ int primID = guo.getPrimTypeID();
508+ String methodSignature = guo.getSignature();
509+ CompositeType comptype = guo.getCompositeType();
510+ SurfaceType dsttype = guo.getDestType();
511+
512+ Blit convertdst = createConverter(dsttype, SurfaceType.IntArgb);
513+ GraphicsPrimitive performop = getGeneralOp(primID, comptype);
514+ Blit convertres = createConverter(SurfaceType.IntArgb, dsttype);
515+ if (convertdst == null || performop == null || convertres == null) {
516+ throw new InternalError("Cannot construct binary op for "+
517+ comptype+" "+dsttype);
518+ }
519+
520+ guo.setPrimitives(convertdst, performop, convertres);
521+ }
522+
523+ protected static Blit createConverter(SurfaceType srctype,
524+ SurfaceType dsttype)
525+ {
526+ if (srctype.equals(dsttype)) {
527+ return null;
528+ }
529+ Blit cv = Blit.getFromCache(srctype, CompositeType.SrcNoEa, dsttype);
530+ if (cv == null) {
531+ throw new InternalError("Cannot construct converter for "+
532+ srctype+"=>"+dsttype);
533+ }
534+ return cv;
535+ }
536+
537+ protected static SurfaceData convertFrom(Blit ob, SurfaceData srcData,
538+ int srcX, int srcY, int w, int h,
539+ SurfaceData dstData)
540+ {
541+ return convertFrom(ob, srcData,
542+ srcX, srcY, w, h, dstData,
543+ BufferedImage.TYPE_INT_ARGB);
544+ }
545+
546+ protected static SurfaceData convertFrom(Blit ob, SurfaceData srcData,
547+ int srcX, int srcY, int w, int h,
548+ SurfaceData dstData, int type)
549+ {
550+ if (dstData != null) {
551+ Rectangle r = dstData.getBounds();
552+ if (w > r.width || h > r.height) {
553+ dstData = null;
554+ }
555+ }
556+ if (dstData == null) {
557+ BufferedImage dstBI = new BufferedImage(w, h, type);
558+ dstData = BufImgSurfaceData.createData(dstBI);
559+ }
560+ ob.Blit(srcData, dstData, AlphaComposite.Src, null,
561+ srcX, srcY, 0, 0, w, h);
562+ return dstData;
563+ }
564+
565+ protected static void convertTo(Blit ob,
566+ SurfaceData srcImg, SurfaceData dstImg,
567+ Region clip,
568+ int dstX, int dstY, int w, int h)
569+ {
570+ if (ob != null) {
571+ ob.Blit(srcImg, dstImg, AlphaComposite.Src, clip,
572+ 0, 0, dstX, dstY, w, h);
573+ }
574+ }
575+
576+ protected static GraphicsPrimitive getGeneralOp(int primID,
577+ CompositeType comptype)
578+ {
579+ return GraphicsPrimitiveMgr.locatePrim(primID,
580+ SurfaceType.IntArgb,
581+ comptype,
582+ SurfaceType.IntArgb);
583+ }
584+
585+ public static String simplename(Field[] fields, Object o) {
586+ for (int i = 0; i < fields.length; i++) {
587+ Field f = fields[i];
588+ try {
589+ if (o == f.get(null)) {
590+ return f.getName();
591+ }
592+ } catch (Exception e) {
593+ }
594+ }
595+ return "\""+o.toString()+"\"";
596+ }
597+
598+ public static String simplename(SurfaceType st) {
599+ return simplename(SurfaceType.class.getDeclaredFields(), st);
600+ }
601+
602+ public static String simplename(CompositeType ct) {
603+ return simplename(CompositeType.class.getDeclaredFields(), ct);
604+ }
605+
606+ private String cachedname;
607+
608+ public String toString() {
609+ if (cachedname == null) {
610+ String sig = methodSignature;
611+ int index = sig.indexOf('(');
612+ if (index >= 0) {
613+ sig = sig.substring(0, index);
614+ }
615+ cachedname = (getClass().getName()+"::"+
616+ sig+"("+
617+ simplename(sourceType)+", "+
618+ simplename(compositeType)+", "+
619+ simplename(destType)+")");
620+ }
621+ return cachedname;
622+ }
623+}
java/pkg/sun/java2d/loops/GraphicsPrimitiveMgr$1.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/GraphicsPrimitiveMgr$2.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/GraphicsPrimitiveMgr$PrimitiveSpec.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/GraphicsPrimitiveMgr.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/GraphicsPrimitiveMgr.java+330−0
@@ -0,0 +1,330 @@
1+/*
2+ * Copyright (c) 1997, 2006, 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+
26+/*
27+ * @author Charlton Innovations, Inc.
28+ */
29+
30+package sun.java2d.loops;
31+
32+import java.util.Comparator;
33+import java.util.Arrays;
34+import sun.java2d.SunGraphics2D;
35+
36+/**
37+ * GraphicsComponentMgr provides services to
38+ * 1. register primitives for later use
39+ * 2. locate an instance of a primitve based on characteristics
40+ */
41+public final class GraphicsPrimitiveMgr {
42+
43+ private static final boolean debugTrace = false;
44+ private static GraphicsPrimitive primitives[];
45+ private static GraphicsPrimitive generalPrimitives[];
46+ private static boolean needssort = true;
47+
48+ private static native void initIDs(Class GP, Class ST, Class CT,
49+ Class SG2D, Class Color, Class AT,
50+ Class XORComp, Class AlphaComp,
51+ Class Path2D, Class Path2DFloat,
52+ Class SHints);
53+ private static native void registerNativeLoops();
54+
55+ static {
56+ initIDs(GraphicsPrimitive.class,
57+ SurfaceType.class,
58+ CompositeType.class,
59+ SunGraphics2D.class,
60+ java.awt.Color.class,
61+ java.awt.geom.AffineTransform.class,
62+ XORComposite.class,
63+ java.awt.AlphaComposite.class,
64+ java.awt.geom.Path2D.class,
65+ java.awt.geom.Path2D.Float.class,
66+ sun.awt.SunHints.class);
67+ CustomComponent.register();
68+ GeneralRenderer.register();
69+ registerNativeLoops();
70+ }
71+
72+ private static class PrimitiveSpec {
73+ public int uniqueID;
74+ }
75+
76+ private static Comparator primSorter = new Comparator() {
77+ public int compare(Object o1, Object o2) {
78+ int id1 = ((GraphicsPrimitive) o1).getUniqueID();
79+ int id2 = ((GraphicsPrimitive) o2).getUniqueID();
80+
81+ return (id1 == id2 ? 0 : (id1 < id2 ? -1 : 1));
82+ }
83+ };
84+
85+ private static Comparator primFinder = new Comparator() {
86+ public int compare(Object o1, Object o2) {
87+ int id1 = ((GraphicsPrimitive) o1).getUniqueID();
88+ int id2 = ((PrimitiveSpec) o2).uniqueID;
89+
90+ return (id1 == id2 ? 0 : (id1 < id2 ? -1 : 1));
91+ }
92+ };
93+
94+ /**
95+ * Ensure that noone can instantiate this class.
96+ */
97+ private GraphicsPrimitiveMgr() {
98+ }
99+
100+ public synchronized static void register(GraphicsPrimitive[] newPrimitives)
101+ {
102+ GraphicsPrimitive[] devCollection = primitives;
103+ int oldSize = 0;
104+ int newSize = newPrimitives.length;
105+ if (debugTrace) {
106+ writeLog("Registering " + newSize + " primitives");
107+ for (int i = 0; i < newSize; i++) {
108+ writeLog(newPrimitives[i].toString());
109+ }
110+ }
111+ if (devCollection != null) {
112+ oldSize = devCollection.length;
113+ }
114+ GraphicsPrimitive[] temp = new GraphicsPrimitive[oldSize + newSize];
115+ if (devCollection != null) {
116+ System.arraycopy(devCollection, 0, temp, 0, oldSize);
117+ }
118+ System.arraycopy(newPrimitives, 0, temp, oldSize, newSize);
119+ needssort = true;
120+ primitives = temp;
121+ }
122+
123+ public synchronized static void registerGeneral(GraphicsPrimitive gen) {
124+ if (generalPrimitives == null) {
125+ generalPrimitives = new GraphicsPrimitive[] {gen};
126+ return;
127+ }
128+ int len = generalPrimitives.length;
129+ GraphicsPrimitive[] newGen = new GraphicsPrimitive[len + 1];
130+ System.arraycopy(generalPrimitives, 0, newGen, 0, len);
131+ newGen[len] = gen;
132+ generalPrimitives = newGen;
133+ }
134+
135+ public synchronized static GraphicsPrimitive locate(int primTypeID,
136+ SurfaceType dsttype)
137+ {
138+ return locate(primTypeID,
139+ SurfaceType.OpaqueColor,
140+ CompositeType.Src,
141+ dsttype);
142+ }
143+
144+ public synchronized static GraphicsPrimitive locate(int primTypeID,
145+ SurfaceType srctype,
146+ CompositeType comptype,
147+ SurfaceType dsttype)
148+ {
149+ /*
150+ System.out.println("Looking for:");
151+ System.out.println(" method: "+signature);
152+ System.out.println(" from: "+srctype);
153+ System.out.println(" by: "+comptype);
154+ System.out.println(" to: "+dsttype);
155+ */
156+ GraphicsPrimitive prim = locatePrim(primTypeID,
157+ srctype, comptype, dsttype);
158+
159+ if (prim == null) {
160+ //System.out.println("Trying general loop");
161+ prim = locateGeneral(primTypeID);
162+ if (prim != null) {
163+ prim = prim.makePrimitive(srctype, comptype, dsttype);
164+ if (prim != null && GraphicsPrimitive.traceflags != 0) {
165+ prim = prim.traceWrap();
166+ }
167+ }
168+ }
169+ return prim;
170+ }
171+
172+ public synchronized static GraphicsPrimitive
173+ locatePrim(int primTypeID,
174+ SurfaceType srctype,
175+ CompositeType comptype,
176+ SurfaceType dsttype)
177+ {
178+ /*
179+ System.out.println("Looking for:");
180+ System.out.println(" method: "+signature);
181+ System.out.println(" from: "+srctype);
182+ System.out.println(" by: "+comptype);
183+ System.out.println(" to: "+dsttype);
184+ */
185+ SurfaceType src, dst;
186+ CompositeType cmp;
187+ GraphicsPrimitive prim;
188+ PrimitiveSpec spec = new PrimitiveSpec();
189+
190+ for (dst = dsttype; dst != null; dst = dst.getSuperType()) {
191+ for (src = srctype; src != null; src = src.getSuperType()) {
192+ for (cmp = comptype; cmp != null; cmp = cmp.getSuperType()) {
193+ /*
194+ System.out.println("Trying:");
195+ System.out.println(" method: "+spec.methodSignature);
196+ System.out.println(" from: "+spec.sourceType);
197+ System.out.println(" by: "+spec.compType);
198+ System.out.println(" to: "+spec.destType);
199+ */
200+
201+ spec.uniqueID =
202+ GraphicsPrimitive.makeUniqueID(primTypeID, src, cmp, dst);
203+ prim = locate(spec);
204+ if (prim != null) {
205+ //System.out.println("<GPMgr> Found: " + prim + " in " + i + " steps");
206+ return prim;
207+ }
208+ }
209+ }
210+ }
211+ return null;
212+ }
213+
214+ private static GraphicsPrimitive locateGeneral(int primTypeID) {
215+ if (generalPrimitives == null) {
216+ return null;
217+ }
218+ for (int i = 0; i < generalPrimitives.length; i++) {
219+ GraphicsPrimitive prim = generalPrimitives[i];
220+ if (prim.getPrimTypeID() == primTypeID) {
221+ return prim;
222+ }
223+ }
224+ return null;
225+ //throw new InternalError("No general handler registered for"+signature);
226+ }
227+
228+ private static GraphicsPrimitive locate(PrimitiveSpec spec) {
229+ if (needssort) {
230+ if (GraphicsPrimitive.traceflags != 0) {
231+ for (int i = 0; i < primitives.length; i++) {
232+ primitives[i] = primitives[i].traceWrap();
233+ }
234+ }
235+ Arrays.sort(primitives, primSorter);
236+ needssort = false;
237+ }
238+ GraphicsPrimitive[] devCollection = primitives;
239+ if (devCollection == null) {
240+ return null;
241+ }
242+ int index = Arrays.binarySearch(devCollection, spec, primFinder);
243+ if (index >= 0) {
244+ GraphicsPrimitive prim = devCollection[index];
245+ if (prim instanceof GraphicsPrimitiveProxy) {
246+ prim = ((GraphicsPrimitiveProxy) prim).instantiate();
247+ devCollection[index] = prim;
248+ if (debugTrace) {
249+ writeLog("Instantiated graphics primitive " + prim);
250+ }
251+ }
252+ if (debugTrace) {
253+ writeLog("Lookup found[" + index + "]["+ prim + "]");
254+ }
255+ return prim;
256+ }
257+ if (debugTrace) {
258+ writeLog("Lookup found nothing for:");
259+ writeLog(" " + spec.uniqueID);
260+ }
261+ return null;
262+ }
263+
264+ private static void writeLog(String str) {
265+ if (debugTrace) {
266+ System.err.println(str);
267+ }
268+ }
269+
270+ /**
271+ * Test that all of the GraphicsPrimitiveProxy objects actually
272+ * resolve to something. Throws a RuntimeException if anything
273+ * is wrong, an has no effect if all is well.
274+ */
275+ // This is only really meant to be called from GraphicsPrimitiveProxyTest
276+ // in the regression tests directory, but it has to be here because
277+ // it needs access to a private data structure. It is not very
278+ // big, though.
279+ public static void testPrimitiveInstantiation() {
280+ testPrimitiveInstantiation(false);
281+ }
282+
283+ public static void testPrimitiveInstantiation(boolean verbose) {
284+ int resolved = 0;
285+ int unresolved = 0;
286+ GraphicsPrimitive[] prims = primitives;
287+ for (int j = 0; j < prims.length; j++) {
288+ GraphicsPrimitive p = prims[j];
289+ if (p instanceof GraphicsPrimitiveProxy) {
290+ GraphicsPrimitive r = ((GraphicsPrimitiveProxy) p).instantiate();
291+ if (!r.getSignature().equals(p.getSignature()) ||
292+ r.getUniqueID() != p.getUniqueID()) {
293+ System.out.println("r.getSignature == "+r.getSignature());
294+ System.out.println("r.getUniqueID == " + r.getUniqueID());
295+ System.out.println("p.getSignature == "+p.getSignature());
296+ System.out.println("p.getUniqueID == " + p.getUniqueID());
297+ throw new RuntimeException("Primitive " + p
298+ + " returns wrong signature for "
299+ + r.getClass());
300+ }
301+ // instantiate checks that p.satisfiesSameAs(r)
302+ unresolved++;
303+ p = r;
304+ if (verbose) {
305+ System.out.println(p);
306+ }
307+ } else {
308+ if (verbose) {
309+ System.out.println(p + " (not proxied).");
310+ }
311+ resolved++;
312+ }
313+ }
314+ System.out.println(resolved+
315+ " graphics primitives were not proxied.");
316+ System.out.println(unresolved+
317+ " proxied graphics primitives resolved correctly.");
318+ System.out.println(resolved+unresolved+
319+ " total graphics primitives");
320+ }
321+
322+ public static void main(String argv[]) {
323+ // REMIND: Should trigger loading of platform primitives somehow...
324+ if (needssort) {
325+ Arrays.sort(primitives, primSorter);
326+ needssort = false;
327+ }
328+ testPrimitiveInstantiation(argv.length > 0);
329+ }
330+}
java/pkg/sun/java2d/loops/GraphicsPrimitiveProxy.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/GraphicsPrimitiveProxy.java+114−0
@@ -0,0 +1,114 @@
1+/*
2+ * Copyright (c) 1998, 2003, 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+
26+package sun.java2d.loops;
27+
28+/**
29+ * GraphicsPrimitiveProxy
30+ *
31+ * Acts as a proxy for instances of GraphicsPrimitive, enabling lazy
32+ * classloading of these primitives. This leads to a substantial
33+ * savings in start-up time and footprint. In the typical case,
34+ * it has been found that a small number of GraphicsPrimitive instance
35+ * actually end up getting instantiated.
36+ * <p>
37+ * Note that the makePrimitive method should never be invoked on
38+ * a GraphicsPrimitiveProxy object since they are instantiated as
39+ * soon as they are found in the primitive list and never returned
40+ * to the caller.
41+ */
42+public class GraphicsPrimitiveProxy extends GraphicsPrimitive {
43+
44+ private Class owner;
45+ private String relativeClassName;
46+
47+ /**
48+ * Create a GraphicsPrimitiveProxy for a primitive with a no-argument
49+ * constructor.
50+ *
51+ * @param owner The owner class for this primitive. The primitive
52+ * must be in the same package as this owner.
53+ * @param relativeClassName The name of the class this is a proxy for.
54+ * This should not include the package.
55+ */
56+ public GraphicsPrimitiveProxy(Class owner, String relativeClassName,
57+ String methodSignature,
58+ int primID,
59+ SurfaceType srctype,
60+ CompositeType comptype,
61+ SurfaceType dsttype)
62+ {
63+ super(methodSignature, primID, srctype, comptype, dsttype);
64+ this.owner = owner;
65+ this.relativeClassName = relativeClassName;
66+ }
67+
68+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
69+ CompositeType comptype,
70+ SurfaceType dsttype) {
71+ // This should never happen.
72+ throw new InternalError("makePrimitive called on a Proxy!");
73+ }
74+
75+ //
76+ // Come up with the real instance. Called from
77+ // GraphicsPrimitiveMgr.locate()
78+ //
79+ GraphicsPrimitive instantiate() {
80+ String name = getPackageName(owner.getName()) + "."
81+ + relativeClassName;
82+ try {
83+ Class clazz = Class.forName(name);
84+ GraphicsPrimitive p = (GraphicsPrimitive) clazz.newInstance();
85+ if (!satisfiesSameAs(p)) {
86+ throw new RuntimeException("Primitive " + p
87+ + " incompatible with proxy for "
88+ + name);
89+ }
90+ return p;
91+ } catch (ClassNotFoundException ex) {
92+ throw new RuntimeException(ex.toString());
93+ } catch (InstantiationException ex) {
94+ throw new RuntimeException(ex.toString());
95+ } catch (IllegalAccessException ex) {
96+ throw new RuntimeException(ex.toString());
97+ }
98+ // A RuntimeException should never happen in a deployed JDK, because
99+ // the regression test GraphicsPrimitiveProxyTest will catch any
100+ // of these errors.
101+ }
102+
103+ private static String getPackageName(String className) {
104+ int lastDotIdx = className.lastIndexOf('.');
105+ if (lastDotIdx < 0) {
106+ return className;
107+ }
108+ return className.substring(0, lastDotIdx);
109+ }
110+
111+ public GraphicsPrimitive traceWrap() {
112+ return instantiate().traceWrap();
113+ }
114+}
java/pkg/sun/java2d/loops/MaskBlit$General.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/MaskBlit$TraceMaskBlit.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/MaskBlit.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/MaskBlit.java+264−0
@@ -0,0 +1,264 @@
1+/*
2+ * Copyright (c) 1999, 2004, 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+
26+package sun.java2d.loops;
27+
28+import java.awt.Composite;
29+import java.lang.ref.WeakReference;
30+import sun.java2d.loops.GraphicsPrimitive;
31+import sun.java2d.SurfaceData;
32+import sun.java2d.pipe.Region;
33+
34+/**
35+ * MaskBlit
36+ * 1) copies rectangle of pixels from one surface to another
37+ * 2) performs compositing of colors based upon a Composite
38+ * parameter
39+ * 3) blends result of composite with destination using an
40+ * alpha coverage mask
41+ * 4) the mask may be null in which case it should be treated
42+ * as if it were an array of all opaque values (0xff)
43+ *
44+ * precise behavior is undefined if the source surface
45+ * and the destination surface are the same surface
46+ * with overlapping regions of pixels
47+ */
48+
49+public class MaskBlit extends GraphicsPrimitive
50+{
51+ public static final String methodSignature = "MaskBlit(...)".toString();
52+
53+ public static final int primTypeID = makePrimTypeID();
54+
55+ private static RenderCache blitcache = new RenderCache(20);
56+
57+ public static MaskBlit locate(SurfaceType srctype,
58+ CompositeType comptype,
59+ SurfaceType dsttype)
60+ {
61+ return (MaskBlit)
62+ GraphicsPrimitiveMgr.locate(primTypeID,
63+ srctype, comptype, dsttype);
64+ }
65+
66+ public static MaskBlit getFromCache(SurfaceType src,
67+ CompositeType comp,
68+ SurfaceType dst)
69+ {
70+ Object o = blitcache.get(src, comp, dst);
71+ if (o != null) {
72+ return (MaskBlit) o;
73+ }
74+ MaskBlit blit = locate(src, comp, dst);
75+ if (blit == null) {
76+ System.out.println("mask blit loop not found for:");
77+ System.out.println("src: "+src);
78+ System.out.println("comp: "+comp);
79+ System.out.println("dst: "+dst);
80+ } else {
81+ blitcache.put(src, comp, dst, blit);
82+ }
83+ return blit;
84+ }
85+
86+ protected MaskBlit(SurfaceType srctype,
87+ CompositeType comptype,
88+ SurfaceType dsttype)
89+ {
90+ super(methodSignature, primTypeID, srctype, comptype, dsttype);
91+ }
92+
93+ public MaskBlit(long pNativePrim,
94+ SurfaceType srctype,
95+ CompositeType comptype,
96+ SurfaceType dsttype)
97+ {
98+ super(pNativePrim, methodSignature, primTypeID, srctype, comptype, dsttype);
99+ }
100+
101+ /**
102+ * All MaskBlit implementors must have this invoker method
103+ */
104+ public native void MaskBlit(SurfaceData src, SurfaceData dst,
105+ Composite comp, Region clip,
106+ int srcx, int srcy,
107+ int dstx, int dsty,
108+ int width, int height,
109+ byte[] mask, int maskoff, int maskscan);
110+
111+ static {
112+ GraphicsPrimitiveMgr.registerGeneral(new MaskBlit(null, null, null));
113+ }
114+
115+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
116+ CompositeType comptype,
117+ SurfaceType dsttype)
118+ {
119+ /*
120+ new Throwable().printStackTrace();
121+ System.out.println("Constructing general maskblit for:");
122+ System.out.println("src: "+srctype);
123+ System.out.println("comp: "+comptype);
124+ System.out.println("dst: "+dsttype);
125+ */
126+
127+ if (CompositeType.Xor.equals(comptype)) {
128+ throw new InternalError("Cannot construct MaskBlit for " +
129+ "XOR mode");
130+ }
131+
132+ General ob = new General(srctype, comptype, dsttype);
133+ setupGeneralBinaryOp(ob);
134+ return ob;
135+ }
136+
137+ private static class General
138+ extends MaskBlit
139+ implements GeneralBinaryOp
140+ {
141+ Blit convertsrc;
142+ Blit convertdst;
143+ MaskBlit performop;
144+ Blit convertresult;
145+
146+ WeakReference srcTmp;
147+ WeakReference dstTmp;
148+
149+ public General(SurfaceType srctype,
150+ CompositeType comptype,
151+ SurfaceType dsttype)
152+ {
153+ super(srctype, comptype, dsttype);
154+ }
155+
156+ public void setPrimitives(Blit srcconverter,
157+ Blit dstconverter,
158+ GraphicsPrimitive genericop,
159+ Blit resconverter)
160+ {
161+ this.convertsrc = srcconverter;
162+ this.convertdst = dstconverter;
163+ this.performop = (MaskBlit) genericop;
164+ this.convertresult = resconverter;
165+ }
166+
167+ public synchronized void MaskBlit(SurfaceData srcData,
168+ SurfaceData dstData,
169+ Composite comp,
170+ Region clip,
171+ int srcx, int srcy,
172+ int dstx, int dsty,
173+ int width, int height,
174+ byte mask[], int offset, int scan)
175+ {
176+ SurfaceData src, dst;
177+ Region opclip;
178+ int sx, sy, dx, dy;
179+
180+ if (convertsrc == null) {
181+ src = srcData;
182+ sx = srcx;
183+ sy = srcy;
184+ } else {
185+ SurfaceData cachedSrc = null;
186+ if (srcTmp != null) {
187+ cachedSrc = (SurfaceData) srcTmp.get();
188+ }
189+ src = convertFrom(convertsrc, srcData, srcx, srcy,
190+ width, height, cachedSrc);
191+ sx = 0;
192+ sy = 0;
193+ if (src != cachedSrc) {
194+ srcTmp = new WeakReference(src);
195+ }
196+ }
197+
198+ if (convertdst == null) {
199+ dst = dstData;
200+ dx = dstx;
201+ dy = dsty;
202+ opclip = clip;
203+ } else {
204+ // assert: convertresult != null
205+ SurfaceData cachedDst = null;
206+ if (dstTmp != null) {
207+ cachedDst = (SurfaceData) dstTmp.get();
208+ }
209+ dst = convertFrom(convertdst, dstData, dstx, dsty,
210+ width, height, cachedDst);
211+ dx = 0;
212+ dy = 0;
213+ opclip = null;
214+ if (dst != cachedDst) {
215+ dstTmp = new WeakReference(dst);
216+ }
217+ }
218+
219+ performop.MaskBlit(src, dst, comp, opclip,
220+ sx, sy, dx, dy, width, height,
221+ mask, offset, scan);
222+
223+ if (convertresult != null) {
224+ // assert: convertdst != null
225+ convertTo(convertresult, dst, dstData, clip,
226+ dstx, dsty, width, height);
227+ }
228+ }
229+ }
230+
231+ public GraphicsPrimitive traceWrap() {
232+ return new TraceMaskBlit(this);
233+ }
234+
235+ private static class TraceMaskBlit extends MaskBlit {
236+ MaskBlit target;
237+
238+ public TraceMaskBlit(MaskBlit target) {
239+ // We need to have the same NativePrim as our
240+ // target in case we are used with a TransformHelper
241+ super(target.getNativePrim(),
242+ target.getSourceType(),
243+ target.getCompositeType(),
244+ target.getDestType());
245+ this.target = target;
246+ }
247+
248+ public GraphicsPrimitive traceWrap() {
249+ return this;
250+ }
251+
252+ public void MaskBlit(SurfaceData src, SurfaceData dst,
253+ Composite comp, Region clip,
254+ int srcx, int srcy, int dstx, int dsty,
255+ int width, int height,
256+ byte[] mask, int maskoff, int maskscan)
257+ {
258+ tracePrimitive(target);
259+ target.MaskBlit(src, dst, comp, clip,
260+ srcx, srcy, dstx, dsty, width, height,
261+ mask, maskoff, maskscan);
262+ }
263+ }
264+}
java/pkg/sun/java2d/loops/MaskFill$General.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/MaskFill$TraceMaskFill.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/MaskFill.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/MaskFill.java+273−0
@@ -0,0 +1,273 @@
1+/*
2+ * Copyright (c) 1999, 2010, 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+
26+package sun.java2d.loops;
27+
28+import java.awt.Paint;
29+import java.awt.PaintContext;
30+import java.awt.Composite;
31+import java.awt.Rectangle;
32+import java.awt.image.ColorModel;
33+import java.awt.image.BufferedImage;
34+import java.awt.image.WritableRaster;
35+import sun.awt.image.BufImgSurfaceData;
36+import sun.java2d.loops.GraphicsPrimitive;
37+import sun.java2d.SunGraphics2D;
38+import sun.java2d.SurfaceData;
39+
40+/**
41+ * MaskFill
42+ * 1) fills rectangles of pixels on a surface
43+ * 2) performs compositing of colors based upon a Composite
44+ * parameter
45+ * 3) blends result of composite with destination using an
46+ * alpha coverage mask
47+ * 4) the mask may be null in which case it should be treated
48+ * as if it were an array of all opaque values (0xff)
49+ */
50+public class MaskFill extends GraphicsPrimitive
51+{
52+ public static final String methodSignature = "MaskFill(...)".toString();
53+ public static final String fillPgramSignature =
54+ "FillAAPgram(...)".toString();
55+ public static final String drawPgramSignature =
56+ "DrawAAPgram(...)".toString();
57+
58+ public static final int primTypeID = makePrimTypeID();
59+
60+ private static RenderCache fillcache = new RenderCache(10);
61+
62+ public static MaskFill locate(SurfaceType srctype,
63+ CompositeType comptype,
64+ SurfaceType dsttype)
65+ {
66+ return (MaskFill)
67+ GraphicsPrimitiveMgr.locate(primTypeID,
68+ srctype, comptype, dsttype);
69+ }
70+
71+ public static MaskFill locatePrim(SurfaceType srctype,
72+ CompositeType comptype,
73+ SurfaceType dsttype)
74+ {
75+ return (MaskFill)
76+ GraphicsPrimitiveMgr.locatePrim(primTypeID,
77+ srctype, comptype, dsttype);
78+ }
79+
80+ /*
81+ * Note that this uses locatePrim, not locate, so it can return
82+ * null if there is no specific loop to handle this op...
83+ */
84+ public static MaskFill getFromCache(SurfaceType src,
85+ CompositeType comp,
86+ SurfaceType dst)
87+ {
88+ Object o = fillcache.get(src, comp, dst);
89+ if (o != null) {
90+ return (MaskFill) o;
91+ }
92+ MaskFill fill = locatePrim(src, comp, dst);
93+ if (fill != null) {
94+ fillcache.put(src, comp, dst, fill);
95+ }
96+ return fill;
97+ }
98+
99+ protected MaskFill(String alternateSignature,
100+ SurfaceType srctype,
101+ CompositeType comptype,
102+ SurfaceType dsttype)
103+ {
104+ super(alternateSignature, primTypeID, srctype, comptype, dsttype);
105+ }
106+
107+ protected MaskFill(SurfaceType srctype,
108+ CompositeType comptype,
109+ SurfaceType dsttype)
110+ {
111+ super(methodSignature, primTypeID, srctype, comptype, dsttype);
112+ }
113+
114+ public MaskFill(long pNativePrim,
115+ SurfaceType srctype,
116+ CompositeType comptype,
117+ SurfaceType dsttype)
118+ {
119+ super(pNativePrim, methodSignature, primTypeID, srctype, comptype, dsttype);
120+ }
121+
122+ /**
123+ * All MaskFill implementors must have this invoker method
124+ */
125+ public native void MaskFill(SunGraphics2D sg2d, SurfaceData sData,
126+ Composite comp,
127+ int x, int y, int w, int h,
128+ byte[] mask, int maskoff, int maskscan);
129+
130+ public native void FillAAPgram(SunGraphics2D sg2d, SurfaceData sData,
131+ Composite comp,
132+ double x, double y,
133+ double dx1, double dy1,
134+ double dx2, double dy2);
135+
136+ public native void DrawAAPgram(SunGraphics2D sg2d, SurfaceData sData,
137+ Composite comp,
138+ double x, double y,
139+ double dx1, double dy1,
140+ double dx2, double dy2,
141+ double lw1, double lw2);
142+
143+ public boolean canDoParallelograms() {
144+ return (getNativePrim() != 0);
145+ }
146+
147+ static {
148+ GraphicsPrimitiveMgr.registerGeneral(new MaskFill(null, null, null));
149+ }
150+
151+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
152+ CompositeType comptype,
153+ SurfaceType dsttype)
154+ {
155+ if (SurfaceType.OpaqueColor.equals(srctype) ||
156+ SurfaceType.AnyColor.equals(srctype))
157+ {
158+ if (CompositeType.Xor.equals(comptype)) {
159+ throw new InternalError("Cannot construct MaskFill for " +
160+ "XOR mode");
161+ } else {
162+ return new General(srctype, comptype, dsttype);
163+ }
164+ } else {
165+ throw new InternalError("MaskFill can only fill with colors");
166+ }
167+ }
168+
169+ private static class General extends MaskFill {
170+ FillRect fillop;
171+ MaskBlit maskop;
172+
173+ public General(SurfaceType srctype,
174+ CompositeType comptype,
175+ SurfaceType dsttype)
176+ {
177+ super(srctype, comptype, dsttype);
178+ fillop = FillRect.locate(srctype,
179+ CompositeType.SrcNoEa,
180+ SurfaceType.IntArgb);
181+ maskop = MaskBlit.locate(SurfaceType.IntArgb, comptype, dsttype);
182+ }
183+
184+ public void MaskFill(SunGraphics2D sg2d,
185+ SurfaceData sData,
186+ Composite comp,
187+ int x, int y, int w, int h,
188+ byte mask[], int offset, int scan)
189+ {
190+ BufferedImage dstBI =
191+ new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
192+ SurfaceData tmpData = BufImgSurfaceData.createData(dstBI);
193+
194+ // REMIND: This is not pretty. It would be nicer if we
195+ // passed a "FillData" object to the Pixel loops, instead
196+ // of a SunGraphics2D parameter...
197+ int pixel = sg2d.pixel;
198+ sg2d.pixel = tmpData.pixelFor(sg2d.getColor());
199+ fillop.FillRect(sg2d, tmpData, 0, 0, w, h);
200+ sg2d.pixel = pixel;
201+
202+ maskop.MaskBlit(tmpData, sData, comp, null,
203+ 0, 0, x, y, w, h,
204+ mask, offset, scan);
205+ }
206+ }
207+
208+ public GraphicsPrimitive traceWrap() {
209+ return new TraceMaskFill(this);
210+ }
211+
212+ private static class TraceMaskFill extends MaskFill {
213+ MaskFill target;
214+ MaskFill fillPgramTarget;
215+ MaskFill drawPgramTarget;
216+
217+ public TraceMaskFill(MaskFill target) {
218+ super(target.getSourceType(),
219+ target.getCompositeType(),
220+ target.getDestType());
221+ this.target = target;
222+ this.fillPgramTarget = new MaskFill(fillPgramSignature,
223+ target.getSourceType(),
224+ target.getCompositeType(),
225+ target.getDestType());
226+ this.drawPgramTarget = new MaskFill(drawPgramSignature,
227+ target.getSourceType(),
228+ target.getCompositeType(),
229+ target.getDestType());
230+ }
231+
232+ public GraphicsPrimitive traceWrap() {
233+ return this;
234+ }
235+
236+ public void MaskFill(SunGraphics2D sg2d, SurfaceData sData,
237+ Composite comp,
238+ int x, int y, int w, int h,
239+ byte[] mask, int maskoff, int maskscan)
240+ {
241+ tracePrimitive(target);
242+ target.MaskFill(sg2d, sData, comp, x, y, w, h,
243+ mask, maskoff, maskscan);
244+ }
245+
246+ public void FillAAPgram(SunGraphics2D sg2d, SurfaceData sData,
247+ Composite comp,
248+ double x, double y,
249+ double dx1, double dy1,
250+ double dx2, double dy2)
251+ {
252+ tracePrimitive(fillPgramTarget);
253+ target.FillAAPgram(sg2d, sData, comp,
254+ x, y, dx1, dy1, dx2, dy2);
255+ }
256+
257+ public void DrawAAPgram(SunGraphics2D sg2d, SurfaceData sData,
258+ Composite comp,
259+ double x, double y,
260+ double dx1, double dy1,
261+ double dx2, double dy2,
262+ double lw1, double lw2)
263+ {
264+ tracePrimitive(drawPgramTarget);
265+ target.DrawAAPgram(sg2d, sData, comp,
266+ x, y, dx1, dy1, dx2, dy2, lw1, lw2);
267+ }
268+
269+ public boolean canDoParallelograms() {
270+ return target.canDoParallelograms();
271+ }
272+ }
273+}
java/pkg/sun/java2d/loops/OpaqueCopyAnyToArgb.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/OpaqueCopyArgbToAny.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/PixelWriter.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/PixelWriterDrawHandler.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/ProcessPath$1.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/ProcessPath$ActiveEdgeList.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/ProcessPath$DrawHandler.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/ProcessPath$DrawProcessHandler.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/ProcessPath$Edge.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/ProcessPath$EndSubPathHandler.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/ProcessPath$FillData.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/ProcessPath$FillProcessHandler.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/ProcessPath$Point.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/ProcessPath$ProcessHandler.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/ProcessPath.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/ProcessPath.java+2128−0
@@ -0,0 +1,2128 @@
1+/*
2+ * Copyright (c) 2005, 2006, 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+
26+package sun.java2d.loops;
27+
28+import java.awt.geom.Path2D;
29+import java.awt.geom.PathIterator;
30+import java.awt.geom.QuadCurve2D;
31+import sun.awt.SunHints;
32+import java.util.*;
33+
34+/* This is the java implementation of the native code from
35+ * src/share/native/sun/java2d/loops/ProcessPath.[c,h]
36+ * This code is written to be as much similar to the native
37+ * as it possible. So, it sometimes does not follow java naming conventions.
38+ *
39+ * It's important to keep this code synchronized with native one. See more
40+ * comments, description and high level scheme of the rendering process in the
41+ * ProcessPath.c
42+ */
43+
44+public class ProcessPath {
45+
46+ /* Public interfaces and methods for drawing and filling general paths */
47+
48+ public static abstract class DrawHandler {
49+ public int xMin;
50+ public int yMin;
51+ public int xMax;
52+ public int yMax;
53+ public float xMinf;
54+ public float yMinf;
55+ public float xMaxf;
56+ public float yMaxf;
57+
58+ public int strokeControl;
59+
60+ public DrawHandler(int xMin, int yMin, int xMax, int yMax,
61+ int strokeControl)
62+ {
63+ setBounds(xMin, yMin, xMax, yMax, strokeControl);
64+ }
65+
66+ public void setBounds(int xMin, int yMin, int xMax, int yMax)
67+ {
68+ this.xMin = xMin;
69+ this.yMin = yMin;
70+ this.xMax = xMax;
71+ this.yMax = yMax;
72+
73+ /* Setting up fractional clipping box
74+ *
75+ * We are using following float -> int mapping:
76+ *
77+ * xi = floor(xf + 0.5)
78+ *
79+ * So, fractional values that hit the [xmin, xmax) integer interval
80+ * will be situated inside the [xmin-0.5, xmax - 0.5) fractional
81+ * interval. We are using EPSF constant to provide that upper
82+ * boundary is not included.
83+ */
84+ xMinf = xMin - 0.5f;
85+ yMinf = yMin - 0.5f;
86+ xMaxf = xMax - 0.5f - EPSF;
87+ yMaxf = yMax - 0.5f - EPSF;
88+ }
89+
90+ public void setBounds(int xMin, int yMin, int xMax, int yMax,
91+ int strokeControl)
92+ {
93+ this.strokeControl = strokeControl;
94+ setBounds(xMin, yMin, xMax, yMax);
95+ }
96+
97+ public void adjustBounds(int bxMin, int byMin, int bxMax, int byMax)
98+ {
99+ if (xMin > bxMin) bxMin = xMin;
100+ if (xMax < bxMax) bxMax = xMax;
101+ if (yMin > byMin) byMin = yMin;
102+ if (yMax < byMax) byMax = yMax;
103+ setBounds(bxMin, byMin, bxMax, byMax);
104+ }
105+
106+ public DrawHandler(int xMin, int yMin, int xMax, int yMax) {
107+ this(xMin, yMin, xMax, yMax, SunHints.INTVAL_STROKE_DEFAULT);
108+ }
109+
110+ public abstract void drawLine(int x0, int y0, int x1, int y1);
111+
112+ public abstract void drawPixel(int x0, int y0);
113+
114+ public abstract void drawScanline(int x0, int x1, int y0);
115+ }
116+
117+ public interface EndSubPathHandler {
118+ public void processEndSubPath();
119+ }
120+
121+ public static final int PH_MODE_DRAW_CLIP = 0;
122+ public static final int PH_MODE_FILL_CLIP = 1;
123+
124+ public static abstract class ProcessHandler implements EndSubPathHandler {
125+ DrawHandler dhnd;
126+ int clipMode;
127+
128+ public ProcessHandler(DrawHandler dhnd,
129+ int clipMode) {
130+ this.dhnd = dhnd;
131+ this.clipMode = clipMode;
132+ }
133+
134+ public abstract void processFixedLine(int x1, int y1,
135+ int x2, int y2, int [] pixelInfo,
136+ boolean checkBounds,
137+ boolean endSubPath);
138+ }
139+
140+ public static EndSubPathHandler noopEndSubPathHandler =
141+ new EndSubPathHandler() {
142+ public void processEndSubPath() { }
143+ };
144+
145+ public static boolean fillPath(DrawHandler dhnd, Path2D.Float p2df,
146+ int transX, int transY)
147+ {
148+ FillProcessHandler fhnd = new FillProcessHandler(dhnd);
149+ if (!doProcessPath(fhnd, p2df, transX, transY)) {
150+ return false;
151+ }
152+ FillPolygon(fhnd, p2df.getWindingRule());
153+ return true;
154+ }
155+
156+ public static boolean drawPath(DrawHandler dhnd,
157+ EndSubPathHandler endSubPath,
158+ Path2D.Float p2df,
159+ int transX, int transY)
160+ {
161+ return doProcessPath(new DrawProcessHandler(dhnd, endSubPath),
162+ p2df, transX, transY);
163+ }
164+
165+ public static boolean drawPath(DrawHandler dhnd,
166+ Path2D.Float p2df,
167+ int transX, int transY)
168+ {
169+ return doProcessPath(new DrawProcessHandler(dhnd,
170+ noopEndSubPathHandler),
171+ p2df, transX, transY);
172+ }
173+
174+ /* Private implementation of the rendering process */
175+
176+ /* Boundaries used for skipping huge path segments */
177+ private static final float UPPER_BND = Float.MAX_VALUE/4.0f;
178+ private static final float LOWER_BND = -UPPER_BND;
179+
180+ /* Precision (in bits) used in forward differencing */
181+ private static final int FWD_PREC = 7;
182+
183+ /* Precision (in bits) used for the rounding in the midpoint test */
184+ private static final int MDP_PREC = 10;
185+
186+ private static final int MDP_MULT = 1 << MDP_PREC;
187+ private static final int MDP_HALF_MULT = MDP_MULT >> 1;
188+
189+ /* Boundaries used for clipping large path segments (those are inside
190+ * [UPPER/LOWER]_BND boundaries)
191+ */
192+ private static final int UPPER_OUT_BND = 1 << (30 - MDP_PREC);
193+ private static final int LOWER_OUT_BND = -UPPER_OUT_BND;
194+
195+
196+ /* Calculation boundaries. They are used for switching to the more slow but
197+ * allowing larger input values method of calculation of the initial values
198+ * of the scan converted line segments inside the FillPolygon
199+ */
200+ private static final float CALC_UBND = 1 << (30 - MDP_PREC);
201+ private static final float CALC_LBND = -CALC_UBND;
202+
203+
204+ /* Following constants are used for providing open boundaries of the
205+ * intervals
206+ */
207+ public static final int EPSFX = 1;
208+ public static final float EPSF = ((float)EPSFX)/MDP_MULT;
209+
210+ /* Bit mask used to separate whole part from the fraction part of the
211+ * number
212+ */
213+ private static final int MDP_W_MASK = -MDP_MULT;
214+
215+ /* Bit mask used to separate fractional part from the whole part of the
216+ * number
217+ */
218+ private static final int MDP_F_MASK = MDP_MULT - 1;
219+
220+ /*
221+ * Constants for the forward differencing
222+ * of the cubic and quad curves
223+ */
224+
225+ /* Maximum size of the cubic curve (calculated as the size of the bounding
226+ * box of the control points) which could be rendered without splitting
227+ */
228+ private static final int MAX_CUB_SIZE = 256;
229+
230+ /* Maximum size of the quad curve (calculated as the size of the bounding
231+ * box of the control points) which could be rendered without splitting
232+ */
233+ private static final int MAX_QUAD_SIZE = 1024;
234+
235+ /* Default power of 2 steps used in the forward differencing. Here DF prefix
236+ * stands for DeFault. Constants below are used as initial values for the
237+ * adaptive forward differencing algorithm.
238+ */
239+ private static final int DF_CUB_STEPS = 3;
240+ private static final int DF_QUAD_STEPS = 2;
241+
242+ /* Shift of the current point of the curve for preparing to the midpoint
243+ * rounding
244+ */
245+ private static final int DF_CUB_SHIFT = FWD_PREC + DF_CUB_STEPS*3 -
246+ MDP_PREC;
247+ private static final int DF_QUAD_SHIFT = FWD_PREC + DF_QUAD_STEPS*2 -
248+ MDP_PREC;
249+
250+ /* Default amount of steps of the forward differencing */
251+ private static final int DF_CUB_COUNT = (1<<DF_CUB_STEPS);
252+ private static final int DF_QUAD_COUNT = (1<<DF_QUAD_STEPS);
253+
254+ /* Default boundary constants used to check the necessity of the restepping
255+ */
256+ private static final int DF_CUB_DEC_BND = 1<<DF_CUB_STEPS*3 + FWD_PREC + 2;
257+ private static final int DF_CUB_INC_BND = 1<<DF_CUB_STEPS*3 + FWD_PREC - 1;
258+ private static final int DF_QUAD_DEC_BND = 1<<DF_QUAD_STEPS*2 +
259+ FWD_PREC + 2;
260+ private static final int DF_QUAD_INC_BND = 1<<DF_QUAD_STEPS*2 +
261+ FWD_PREC - 1;
262+
263+ /* Multipliers for the coefficients of the polynomial form of the cubic and
264+ * quad curves representation
265+ */
266+ private static final int CUB_A_SHIFT = FWD_PREC;
267+ private static final int CUB_B_SHIFT = (DF_CUB_STEPS + FWD_PREC + 1);
268+ private static final int CUB_C_SHIFT = (DF_CUB_STEPS*2 + FWD_PREC);
269+
270+ private static final int CUB_A_MDP_MULT = (1<<CUB_A_SHIFT);
271+ private static final int CUB_B_MDP_MULT = (1<<CUB_B_SHIFT);
272+ private static final int CUB_C_MDP_MULT = (1<<CUB_C_SHIFT);
273+
274+ private static final int QUAD_A_SHIFT = FWD_PREC;
275+ private static final int QUAD_B_SHIFT = (DF_QUAD_STEPS + FWD_PREC);
276+
277+ private static final int QUAD_A_MDP_MULT = (1<<QUAD_A_SHIFT);
278+ private static final int QUAD_B_MDP_MULT = (1<<QUAD_B_SHIFT);
279+
280+ /* Clipping macros for drawing and filling algorithms */
281+ private static float CLIP(float a1, float b1, float a2, float b2,
282+ double t) {
283+ return (float)(b1 + (double)(t - a1)*(b2 - b1) / (a2 - a1));
284+ }
285+
286+ private static int CLIP(int a1, int b1, int a2, int b2, double t) {
287+ return (int)(b1 + (double)(t - a1)*(b2 - b1) / (a2 - a1));
288+ }
289+
290+
291+ private static final int CRES_MIN_CLIPPED = 0;
292+ private static final int CRES_MAX_CLIPPED = 1;
293+ private static final int CRES_NOT_CLIPPED = 3;
294+ private static final int CRES_INVISIBLE = 4;
295+
296+ private static boolean IS_CLIPPED(int res) {
297+ return res == CRES_MIN_CLIPPED || res == CRES_MAX_CLIPPED;
298+ }
299+
300+ /* This is java implementation of the macro from ProcessGeneralPath.c.
301+ * To keep the logic of the java code similar to the native one
302+ * array and set of indexes are used to point out the data.
303+ */
304+ private static int TESTANDCLIP(float LINE_MIN, float LINE_MAX, float[] c,
305+ int a1, int b1, int a2, int b2) {
306+ double t;
307+ int res = CRES_NOT_CLIPPED;
308+ if (c[a1] < (LINE_MIN) || c[a1] > (LINE_MAX)) {
309+ if (c[a1] < (LINE_MIN)) {
310+ if (c[a2] < (LINE_MIN)) {
311+ return CRES_INVISIBLE;
312+ };
313+ res = CRES_MIN_CLIPPED;
314+ t = (LINE_MIN);
315+ } else {
316+ if (c[a2] > (LINE_MAX)) {
317+ return CRES_INVISIBLE;
318+ };
319+ res = CRES_MAX_CLIPPED;
320+ t = (LINE_MAX);
321+ }
322+ c[b1] = CLIP(c[a1], c[b1], c[a2], c[b2], t);
323+ c[a1] = (float)t;
324+ }
325+ return res;
326+ }
327+
328+ /* Integer version of the method above */
329+ private static int TESTANDCLIP(int LINE_MIN, int LINE_MAX, int[] c,
330+ int a1, int b1, int a2, int b2) {
331+ double t;
332+ int res = CRES_NOT_CLIPPED;
333+ if (c[a1] < (LINE_MIN) || c[a1] > (LINE_MAX)) {
334+ if (c[a1] < (LINE_MIN)) {
335+ if (c[a2] < (LINE_MIN)) {
336+ return CRES_INVISIBLE;
337+ };
338+ res = CRES_MIN_CLIPPED;
339+ t = (LINE_MIN);
340+ } else {
341+ if (c[a2] > (LINE_MAX)) {
342+ return CRES_INVISIBLE;
343+ };
344+ res = CRES_MAX_CLIPPED;
345+ t = (LINE_MAX);
346+ }
347+ c[b1] = CLIP(c[a1], c[b1], c[a2], c[b2], t);
348+ c[a1] = (int)t;
349+ }
350+ return res;
351+ }
352+
353+
354+
355+ /* Following method is used for clipping and clumping filled shapes.
356+ * An example of this process is shown on the picture below:
357+ * ----+ ----+
358+ * |/ | |/ |
359+ * + | + |
360+ * /| | I |
361+ * / | | I |
362+ * | | | ===> I |
363+ * \ | | I |
364+ * \| | I |
365+ * + | + |
366+ * |\ | |\ |
367+ * | ----+ | ----+
368+ * boundary boundary
369+ *
370+ * We can only perform clipping in case of right side of the output area
371+ * because all segments passed out the right boundary don't influence on the
372+ * result of scan conversion algorithm (it correctly handles half open
373+ * contours).
374+ *
375+ * This is java implementation of the macro from ProcessGeneralPath.c.
376+ * To keep the logic of the java code similar to the native one
377+ * array and set of indexes are used to point out the data.
378+ *
379+ */
380+ private static int CLIPCLAMP(float LINE_MIN, float LINE_MAX, float[] c,
381+ int a1, int b1, int a2, int b2,
382+ int a3, int b3) {
383+ c[a3] = c[a1];
384+ c[b3] = c[b1];
385+ int res = TESTANDCLIP(LINE_MIN, LINE_MAX, c, a1, b1, a2, b2);
386+ if (res == CRES_MIN_CLIPPED) {
387+ c[a3] = c[a1];
388+ } else if (res == CRES_MAX_CLIPPED) {
389+ c[a3] = c[a1];
390+ res = CRES_MAX_CLIPPED;
391+ } else if (res == CRES_INVISIBLE) {
392+ if (c[a1] > LINE_MAX) {
393+ res = CRES_INVISIBLE;
394+ } else {
395+ c[a1] = LINE_MIN;
396+ c[a2] = LINE_MIN;
397+ res = CRES_NOT_CLIPPED;
398+ }
399+ }
400+ return res;
401+ }
402+
403+ /* Integer version of the method above */
404+ private static int CLIPCLAMP(int LINE_MIN, int LINE_MAX, int[] c,
405+ int a1, int b1, int a2, int b2,
406+ int a3, int b3) {
407+ c[a3] = c[a1];
408+ c[b3] = c[b1];
409+ int res = TESTANDCLIP(LINE_MIN, LINE_MAX, c, a1, b1, a2, b2);
410+ if (res == CRES_MIN_CLIPPED) {
411+ c[a3] = c[a1];
412+ } else if (res == CRES_MAX_CLIPPED) {
413+ c[a3] = c[a1];
414+ res = CRES_MAX_CLIPPED;
415+ } else if (res == CRES_INVISIBLE) {
416+ if (c[a1] > LINE_MAX) {
417+ res = CRES_INVISIBLE;
418+ } else {
419+ c[a1] = LINE_MIN;
420+ c[a2] = LINE_MIN;
421+ res = CRES_NOT_CLIPPED;
422+ }
423+ }
424+ return res;
425+ }
426+
427+ private static class DrawProcessHandler extends ProcessHandler {
428+
429+ EndSubPathHandler processESP;
430+
431+ public DrawProcessHandler(DrawHandler dhnd,
432+ EndSubPathHandler processESP) {
433+ super(dhnd, PH_MODE_DRAW_CLIP);
434+ this.dhnd = dhnd;
435+ this.processESP = processESP;
436+ }
437+
438+ public void processEndSubPath() {
439+ processESP.processEndSubPath();
440+ }
441+
442+ void PROCESS_LINE(int fX0, int fY0, int fX1, int fY1,
443+ boolean checkBounds, int[] pixelInfo) {
444+ int X0 = fX0 >> MDP_PREC;
445+ int Y0 = fY0 >> MDP_PREC;
446+ int X1 = fX1 >> MDP_PREC;
447+ int Y1 = fY1 >> MDP_PREC;
448+
449+ /* Handling lines having just one pixel */
450+ if (((X0^X1) | (Y0^Y1)) == 0) {
451+ if (checkBounds &&
452+ (dhnd.yMin > Y0 ||
453+ dhnd.yMax <= Y0 ||
454+ dhnd.xMin > X0 ||
455+ dhnd.xMax <= X0)) return;
456+
457+ if (pixelInfo[0] == 0) {
458+ pixelInfo[0] = 1;
459+ pixelInfo[1] = X0;
460+ pixelInfo[2] = Y0;
461+ pixelInfo[3] = X0;
462+ pixelInfo[4] = Y0;
463+ dhnd.drawPixel(X0, Y0);
464+ } else if ((X0 != pixelInfo[3] || Y0 != pixelInfo[4]) &&
465+ (X0 != pixelInfo[1] || Y0 != pixelInfo[2])) {
466+ dhnd.drawPixel(X0, Y0);
467+ pixelInfo[3] = X0;
468+ pixelInfo[4] = Y0;
469+ }
470+ return;
471+ }
472+
473+ if (!checkBounds ||
474+ (dhnd.yMin <= Y0 &&
475+ dhnd.yMax > Y0 &&
476+ dhnd.xMin <= X0 &&
477+ dhnd.xMax > X0))
478+ {
479+ /* Switch off first pixel of the line before drawing */
480+ if (pixelInfo[0] == 1 &&
481+ ((pixelInfo[1] == X0 && pixelInfo[2] == Y0) ||
482+ (pixelInfo[3] == X0 && pixelInfo[4] == Y0)))
483+ {
484+ dhnd.drawPixel(X0, Y0);
485+ }
486+ }
487+
488+ dhnd.drawLine(X0, Y0, X1, Y1);
489+
490+ if (pixelInfo[0] == 0) {
491+ pixelInfo[0] = 1;
492+ pixelInfo[1] = X0;
493+ pixelInfo[2] = Y0;
494+ pixelInfo[3] = X0;
495+ pixelInfo[4] = Y0;
496+ }
497+
498+ /* Switch on last pixel of the line if it was already
499+ * drawn during rendering of the previous segments
500+ */
501+ if ((pixelInfo[1] == X1 && pixelInfo[2] == Y1) ||
502+ (pixelInfo[3] == X1 && pixelInfo[4] == Y1))
503+ {
504+ if (checkBounds &&
505+ (dhnd.yMin > Y1 ||
506+ dhnd.yMax <= Y1 ||
507+ dhnd.xMin > X1 ||
508+ dhnd.xMax <= X1)) {
509+ return;
510+ }
511+
512+ dhnd.drawPixel(X1, Y1);
513+ }
514+ pixelInfo[3] = X1;
515+ pixelInfo[4] = Y1;
516+ }
517+
518+ void PROCESS_POINT(int fX, int fY, boolean checkBounds,
519+ int[] pixelInfo) {
520+ int _X = fX>> MDP_PREC;
521+ int _Y = fY>> MDP_PREC;
522+ if (checkBounds &&
523+ (dhnd.yMin > _Y ||
524+ dhnd.yMax <= _Y ||
525+ dhnd.xMin > _X ||
526+ dhnd.xMax <= _X)) return;
527+ /*
528+ * (_X,_Y) should be inside boundaries
529+ *
530+ * assert(dhnd.yMin <= _Y &&
531+ * dhnd.yMax > _Y &&
532+ * dhnd.xMin <= _X &&
533+ * dhnd.xMax > _X);
534+ *
535+ */
536+ if (pixelInfo[0] == 0) {
537+ pixelInfo[0] = 1;
538+ pixelInfo[1] = _X;
539+ pixelInfo[2] = _Y;
540+ pixelInfo[3] = _X;
541+ pixelInfo[4] = _Y;
542+ dhnd.drawPixel(_X, _Y);
543+ } else if ((_X != pixelInfo[3] || _Y != pixelInfo[4]) &&
544+ (_X != pixelInfo[1] || _Y != pixelInfo[2])) {
545+ dhnd.drawPixel(_X, _Y);
546+ pixelInfo[3] = _X;
547+ pixelInfo[4] = _Y;
548+ }
549+ }
550+
551+ /* Drawing line with subpixel endpoints
552+ *
553+ * (x1, y1), (x2, y2) - fixed point coordinates of the endpoints
554+ * with MDP_PREC bits for the fractional part
555+ *
556+ * pixelInfo - structure which keeps drawing info for avoiding
557+ * multiple drawing at the same position on the
558+ * screen (required for the XOR mode of drawing)
559+ *
560+ * pixelInfo[0] - state of the drawing
561+ * 0 - no pixel drawn between
562+ * moveTo/close of the path
563+ * 1 - there are drawn pixels
564+ *
565+ * pixelInfo[1,2] - first pixel of the path
566+ * between moveTo/close of the
567+ * path
568+ *
569+ * pixelInfo[3,4] - last drawn pixel between
570+ * moveTo/close of the path
571+ *
572+ * checkBounds - flag showing necessity of checking the clip
573+ *
574+ */
575+ public void processFixedLine(int x1, int y1, int x2, int y2,
576+ int[] pixelInfo, boolean checkBounds,
577+ boolean endSubPath) {
578+
579+ /* Checking if line is inside a (X,Y),(X+MDP_MULT,Y+MDP_MULT) box */
580+ int c = ((x1 ^ x2) | (y1 ^ y2));
581+ int rx1, ry1, rx2, ry2;
582+ if ((c & MDP_W_MASK) == 0) {
583+ /* Checking for the segments with integer coordinates having
584+ * the same start and end points
585+ */
586+ if (c == 0) {
587+ PROCESS_POINT(x1 + MDP_HALF_MULT, y1 + MDP_HALF_MULT,
588+ checkBounds, pixelInfo);
589+ }
590+ return;
591+ }
592+
593+ if (x1 == x2 || y1 == y2) {
594+ rx1 = x1 + MDP_HALF_MULT;
595+ rx2 = x2 + MDP_HALF_MULT;
596+ ry1 = y1 + MDP_HALF_MULT;
597+ ry2 = y2 + MDP_HALF_MULT;
598+ } else {
599+ /* Neither dx nor dy can be zero because of the check above */
600+ int dx = x2 - x1;
601+ int dy = y2 - y1;
602+
603+ /* Floor of x1, y1, x2, y2 */
604+ int fx1 = x1 & MDP_W_MASK;
605+ int fy1 = y1 & MDP_W_MASK;
606+ int fx2 = x2 & MDP_W_MASK;
607+ int fy2 = y2 & MDP_W_MASK;
608+
609+ /* Processing first endpoint */
610+ if (fx1 == x1 || fy1 == y1) {
611+ /* Adding MDP_HALF_MULT to the [xy]1 if f[xy]1 == [xy]1
612+ * will not affect the result
613+ */
614+ rx1 = x1 + MDP_HALF_MULT;
615+ ry1 = y1 + MDP_HALF_MULT;
616+ } else {
617+ /* Boundary at the direction from (x1,y1) to (x2,y2) */
618+ int bx1 = (x1 < x2) ? fx1 + MDP_MULT : fx1;
619+ int by1 = (y1 < y2) ? fy1 + MDP_MULT : fy1;
620+
621+ /* intersection with column bx1 */
622+ int cross = y1 + ((bx1 - x1)*dy)/dx;
623+ if (cross >= fy1 && cross <= fy1 + MDP_MULT) {
624+ rx1 = bx1;
625+ ry1 = cross + MDP_HALF_MULT;
626+ } else {
627+ /* intersection with row by1 */
628+ cross = x1 + ((by1 - y1)*dx)/dy;
629+ rx1 = cross + MDP_HALF_MULT;
630+ ry1 = by1;
631+ }
632+ }
633+
634+ /* Processing second endpoint */
635+ if (fx2 == x2 || fy2 == y2) {
636+ /* Adding MDP_HALF_MULT to the [xy]2 if f[xy]2 == [xy]2
637+ * will not affect the result
638+ */
639+ rx2 = x2 + MDP_HALF_MULT;
640+ ry2 = y2 + MDP_HALF_MULT;
641+ } else {
642+ /* Boundary at the direction from (x2,y2) to (x1,y1) */
643+ int bx2 = (x1 > x2) ? fx2 + MDP_MULT : fx2;
644+ int by2 = (y1 > y2) ? fy2 + MDP_MULT : fy2;
645+
646+ /* intersection with column bx2 */
647+ int cross = y2 + ((bx2 - x2)*dy)/dx;
648+ if (cross >= fy2 && cross <= fy2 + MDP_MULT) {
649+ rx2 = bx2;
650+ ry2 = cross + MDP_HALF_MULT;
651+ } else {
652+ /* intersection with row by2 */
653+ cross = x2 + ((by2 - y2)*dx)/dy;
654+ rx2 = cross + MDP_HALF_MULT;
655+ ry2 = by2;
656+ }
657+ }
658+ }
659+ PROCESS_LINE(rx1, ry1, rx2, ry2, checkBounds, pixelInfo);
660+ }
661+ }
662+
663+ /* Performing drawing of the monotonic in X and Y quadratic curves with
664+ * sizes less than MAX_QUAD_SIZE by using forward differencing method of
665+ * calculation. See comments to the DrawMonotonicQuad in the
666+ * ProcessGeneralPath.c
667+ */
668+ private static void DrawMonotonicQuad(ProcessHandler hnd,
669+ float[] coords,
670+ boolean checkBounds,
671+ int[] pixelInfo) {
672+
673+ int x0 = (int)(coords[0]*MDP_MULT);
674+ int y0 = (int)(coords[1]*MDP_MULT);
675+
676+ int xe = (int)(coords[4]*MDP_MULT);
677+ int ye = (int)(coords[5]*MDP_MULT);
678+
679+ /* Extracting fractional part of coordinates of first control point */
680+ int px = (x0 & (~MDP_W_MASK)) << DF_QUAD_SHIFT;
681+ int py = (y0 & (~MDP_W_MASK)) << DF_QUAD_SHIFT;
682+
683+ /* Setting default amount of steps */
684+ int count = DF_QUAD_COUNT;
685+
686+ /* Setting default shift for preparing to the midpoint rounding */
687+ int shift = DF_QUAD_SHIFT;
688+
689+ int ax = (int)((coords[0] - 2*coords[2] +
690+ coords[4])*QUAD_A_MDP_MULT);
691+ int ay = (int)((coords[1] - 2*coords[3] +
692+ coords[5])*QUAD_A_MDP_MULT);
693+
694+ int bx = (int)((-2*coords[0] + 2*coords[2])*QUAD_B_MDP_MULT);
695+ int by = (int)((-2*coords[1] + 2*coords[3])*QUAD_B_MDP_MULT);
696+
697+ int ddpx = 2*ax;
698+ int ddpy = 2*ay;
699+
700+ int dpx = ax + bx;
701+ int dpy = ay + by;
702+
703+ int x1, y1;
704+
705+ int x2 = x0;
706+ int y2 = y0;
707+
708+ int maxDD = Math.max(Math.abs(ddpx),Math.abs(ddpy));
709+
710+ int dx = xe - x0;
711+ int dy = ye - y0;
712+
713+ int x0w = x0 & MDP_W_MASK;
714+ int y0w = y0 & MDP_W_MASK;
715+
716+ /* Perform decreasing step in 2 times if slope of the first forward
717+ * difference changes too quickly (more than a pixel per step in X or Y
718+ * direction). We can perform adjusting of the step size before the
719+ * rendering loop because the curvature of the quad curve remains the
720+ * same along all the curve
721+ */
722+ while (maxDD > DF_QUAD_DEC_BND) {
723+ dpx = (dpx<<1) - ax;
724+ dpy = (dpy<<1) - ay;
725+ count <<= 1;
726+ maxDD >>= 2;
727+ px <<=2;
728+ py <<=2;
729+ shift += 2;
730+ }
731+
732+ while(count-- > 1) {
733+ px += dpx;
734+ py += dpy;
735+
736+ dpx += ddpx;
737+ dpy += ddpy;
738+
739+ x1 = x2;
740+ y1 = y2;
741+
742+ x2 = x0w + (px >> shift);
743+ y2 = y0w + (py >> shift);
744+
745+ /* Checking that we are not running out of the endpoint and bounding
746+ * violating coordinate. The check is pretty simple because the
747+ * curve passed to the DrawCubic already splitted into the
748+ * monotonic in X and Y pieces
749+ */
750+
751+ /* Bounding x2 by xe */
752+ if (((xe-x2)^dx) < 0) {
753+ x2 = xe;
754+ }
755+
756+ /* Bounding y2 by ye */
757+ if (((ye-y2)^dy) < 0) {
758+ y2 = ye;
759+ }
760+
761+ hnd.processFixedLine(x1, y1, x2, y2, pixelInfo, checkBounds, false);
762+ }
763+
764+ /* We are performing one step less than necessary and use actual
765+ * (xe,ye) endpoint of the curve instead of calculated. This prevent us
766+ * from running above the curve endpoint due to the accumulated errors
767+ * during the iterations.
768+ */
769+
770+ hnd.processFixedLine(x2, y2, xe, ye, pixelInfo, checkBounds, false);
771+ }
772+
773+ /*
774+ * Checking size of the quad curves and split them if necessary.
775+ * Calling DrawMonotonicQuad for the curves of the appropriate size.
776+ * Note: coords array could be changed
777+ */
778+ private static void ProcessMonotonicQuad(ProcessHandler hnd,
779+ float[] coords,
780+ int[] pixelInfo) {
781+
782+ float[] coords1 = new float[6];
783+ float tx, ty;
784+ float xMin, yMin, xMax, yMax;
785+
786+ xMin = xMax = coords[0];
787+ yMin = yMax = coords[1];
788+ for (int i = 2; i < 6; i += 2) {
789+ xMin = (xMin > coords[i])? coords[i] : xMin;
790+ xMax = (xMax < coords[i])? coords[i] : xMax;
791+ yMin = (yMin > coords[i + 1])? coords[i + 1] : yMin;
792+ yMax = (yMax < coords[i + 1])? coords[i + 1] : yMax;
793+ }
794+
795+ if (hnd.clipMode == PH_MODE_DRAW_CLIP) {
796+
797+ /* In case of drawing we could just skip curves which are
798+ * completely out of bounds
799+ */
800+ if (hnd.dhnd.xMaxf < xMin || hnd.dhnd.xMinf > xMax ||
801+ hnd.dhnd.yMaxf < yMin || hnd.dhnd.yMinf > yMax) {
802+ return;
803+ }
804+ } else {
805+
806+ /* In case of filling we could skip curves which are above,
807+ * below and behind the right boundary of the visible area
808+ */
809+
810+ if (hnd.dhnd.yMaxf < yMin || hnd.dhnd.yMinf > yMax ||
811+ hnd.dhnd.xMaxf < xMin)
812+ {
813+ return;
814+ }
815+
816+ /* We could clamp x coordinates to the corresponding boundary
817+ * if the curve is completely behind the left one
818+ */
819+
820+ if (hnd.dhnd.xMinf > xMax) {
821+ coords[0] = coords[2] = coords[4] = hnd.dhnd.xMinf;
822+ }
823+ }
824+
825+ if (xMax - xMin > MAX_QUAD_SIZE || yMax - yMin > MAX_QUAD_SIZE) {
826+ coords1[4] = coords[4];
827+ coords1[5] = coords[5];
828+ coords1[2] = (coords[2] + coords[4])/2.0f;
829+ coords1[3] = (coords[3] + coords[5])/2.0f;
830+ coords[2] = (coords[0] + coords[2])/2.0f;
831+ coords[3] = (coords[1] + coords[3])/2.0f;
832+ coords[4] = coords1[0] = (coords[2] + coords1[2])/2.0f;
833+ coords[5] = coords1[1] = (coords[3] + coords1[3])/2.0f;
834+
835+ ProcessMonotonicQuad(hnd, coords, pixelInfo);
836+
837+ ProcessMonotonicQuad(hnd, coords1, pixelInfo);
838+ } else {
839+ DrawMonotonicQuad(hnd, coords,
840+ /* Set checkBounds parameter if curve intersects
841+ * boundary of the visible area. We know that the
842+ * curve is visible, so the check is pretty
843+ * simple
844+ */
845+ hnd.dhnd.xMinf >= xMin ||
846+ hnd.dhnd.xMaxf <= xMax ||
847+ hnd.dhnd.yMinf >= yMin ||
848+ hnd.dhnd.yMaxf <= yMax,
849+ pixelInfo);
850+ }
851+ }
852+
853+ /*
854+ * Split quadratic curve into monotonic in X and Y parts. Calling
855+ * ProcessMonotonicQuad for each monotonic piece of the curve.
856+ * Note: coords array could be changed
857+ */
858+ private static void ProcessQuad(ProcessHandler hnd, float[] coords,
859+ int[] pixelInfo) {
860+ /* Temporary array for holding parameters corresponding to the extreme
861+ * in X and Y points
862+ */
863+ double params[] = new double[2];
864+ int cnt = 0;
865+ double param;
866+
867+ /* Simple check for monotonicity in X before searching for the extreme
868+ * points of the X(t) function. We first check if the curve is
869+ * monotonic in X by seeing if all of the X coordinates are strongly
870+ * ordered.
871+ */
872+ if ((coords[0] > coords[2] || coords[2] > coords[4]) &&
873+ (coords[0] < coords[2] || coords[2] < coords[4]))
874+ {
875+ /* Searching for extreme points of the X(t) function by solving
876+ * dX(t)
877+ * ---- = 0 equation
878+ * dt
879+ */
880+ double ax = coords[0] - 2*coords[2] + coords[4];
881+ if (ax != 0) {
882+ /* Calculating root of the following equation
883+ * ax*t + bx = 0
884+ */
885+ double bx = coords[0] - coords[2];
886+
887+ param = bx/ax;
888+ if (param < 1.0 && param > 0.0) {
889+ params[cnt++] = param;
890+ }
891+ }
892+ }
893+
894+ /* Simple check for monotonicity in Y before searching for the extreme
895+ * points of the Y(t) function. We first check if the curve is
896+ * monotonic in Y by seeing if all of the Y coordinates are strongly
897+ * ordered.
898+ */
899+ if ((coords[1] > coords[3] || coords[3] > coords[5]) &&
900+ (coords[1] < coords[3] || coords[3] < coords[5]))
901+ {
902+ /* Searching for extreme points of the Y(t) function by solving
903+ * dY(t)
904+ * ----- = 0 equation
905+ * dt
906+ */
907+ double ay = coords[1] - 2*coords[3] + coords[5];
908+
909+ if (ay != 0) {
910+ /* Calculating root of the following equation
911+ * ay*t + by = 0
912+ */
913+ double by = coords[1] - coords[3];
914+
915+ param = by/ay;
916+ if (param < 1.0 && param > 0.0) {
917+ if (cnt > 0) {
918+ /* Inserting parameter only if it differs from
919+ * already stored
920+ */
921+ if (params[0] > param) {
922+ params[cnt++] = params[0];
923+ params[0] = param;
924+ } else if (params[0] < param) {
925+ params[cnt++] = param;
926+ }
927+ } else {
928+ params[cnt++] = param;
929+ }
930+ }
931+ }
932+ }
933+
934+ /* Processing obtained monotonic parts */
935+ switch(cnt) {
936+ case 0:
937+ break;
938+ case 1:
939+ ProcessFirstMonotonicPartOfQuad(hnd, coords, pixelInfo,
940+ (float)params[0]);
941+ break;
942+ case 2:
943+ ProcessFirstMonotonicPartOfQuad(hnd, coords, pixelInfo,
944+ (float)params[0]);
945+ param = params[1] - params[0];
946+ if (param > 0) {
947+ ProcessFirstMonotonicPartOfQuad(hnd, coords, pixelInfo,
948+ /* Scale parameter to match with
949+ * rest of the curve
950+ */
951+ (float)(param/(1.0 - params[0])));
952+ }
953+ break;
954+ }
955+
956+ ProcessMonotonicQuad(hnd,coords,pixelInfo);
957+ }
958+
959+ /*
960+ * Bite the piece of the quadratic curve from start point till the point
961+ * corresponding to the specified parameter then call ProcessQuad for the
962+ * bitten part.
963+ * Note: coords array will be changed
964+ */
965+ private static void ProcessFirstMonotonicPartOfQuad(ProcessHandler hnd,
966+ float[] coords,
967+ int[] pixelInfo,
968+ float t) {
969+ float[] coords1 = new float[6];
970+
971+ coords1[0] = coords[0];
972+ coords1[1] = coords[1];
973+ coords1[2] = coords[0] + t*(coords[2] - coords[0]);
974+ coords1[3] = coords[1] + t*(coords[3] - coords[1]);
975+ coords[2] = coords[2] + t*(coords[4] - coords[2]);
976+ coords[3] = coords[3] + t*(coords[5] - coords[3]);
977+ coords[0] = coords1[4] = coords1[2] + t*(coords[2] - coords1[2]);
978+ coords[1] = coords1[5] = coords1[3] + t*(coords[3] - coords1[3]);
979+
980+ ProcessMonotonicQuad(hnd, coords1, pixelInfo);
981+ }
982+
983+ /* Performing drawing of the monotonic in X and Y cubic curves with sizes
984+ * less than MAX_CUB_SIZE by using forward differencing method of
985+ * calculation. See comments to the DrawMonotonicCubic in the
986+ * ProcessGeneralPath.c
987+ */
988+ private static void DrawMonotonicCubic(ProcessHandler hnd,
989+ float[] coords,
990+ boolean checkBounds,
991+ int[] pixelInfo) {
992+ int x0 = (int)(coords[0]*MDP_MULT);
993+ int y0 = (int)(coords[1]*MDP_MULT);
994+
995+ int xe = (int)(coords[6]*MDP_MULT);
996+ int ye = (int)(coords[7]*MDP_MULT);
997+
998+ /* Extracting fractional part of coordinates of first control point */
999+ int px = (x0 & (~MDP_W_MASK)) << DF_CUB_SHIFT;
1000+ int py = (y0 & (~MDP_W_MASK)) << DF_CUB_SHIFT;
1001+
1002+ /* Setting default boundary values for checking first and second forward
1003+ * difference for the necessity of the restepping. See comments to the
1004+ * boundary values in ProcessQuad for more info.
1005+ */
1006+ int incStepBnd = DF_CUB_INC_BND;
1007+ int decStepBnd = DF_CUB_DEC_BND;
1008+
1009+ /* Setting default amount of steps */
1010+ int count = DF_CUB_COUNT;
1011+
1012+ /* Setting default shift for preparing to the midpoint rounding */
1013+ int shift = DF_CUB_SHIFT;
1014+
1015+ int ax = (int)((-coords[0] + 3*coords[2] - 3*coords[4] +
1016+ coords[6])*CUB_A_MDP_MULT);
1017+ int ay = (int)((-coords[1] + 3*coords[3] - 3*coords[5] +
1018+ coords[7])*CUB_A_MDP_MULT);
1019+
1020+ int bx = (int)((3*coords[0] - 6*coords[2] +
1021+ 3*coords[4])*CUB_B_MDP_MULT);
1022+ int by = (int)((3*coords[1] - 6*coords[3] +
1023+ 3*coords[5])*CUB_B_MDP_MULT);
1024+
1025+ int cx = (int)((-3*coords[0] + 3*coords[2])*(CUB_C_MDP_MULT));
1026+ int cy = (int)((-3*coords[1] + 3*coords[3])*(CUB_C_MDP_MULT));
1027+
1028+ int dddpx = 6*ax;
1029+ int dddpy = 6*ay;
1030+
1031+ int ddpx = dddpx + bx;
1032+ int ddpy = dddpy + by;
1033+
1034+ int dpx = ax + (bx>>1) + cx;
1035+ int dpy = ay + (by>>1) + cy;
1036+
1037+ int x1, y1;
1038+
1039+ int x2 = x0;
1040+ int y2 = y0;
1041+
1042+ /* Calculating whole part of the first point of the curve */
1043+ int x0w = x0 & MDP_W_MASK;
1044+ int y0w = y0 & MDP_W_MASK;
1045+
1046+ int dx = xe - x0;
1047+ int dy = ye - y0;
1048+
1049+ while (count > 0) {
1050+ /* Perform decreasing step in 2 times if necessary */
1051+ while (Math.abs(ddpx) > decStepBnd ||
1052+ Math.abs(ddpy) > decStepBnd) {
1053+ ddpx = (ddpx<<1) - dddpx;
1054+ ddpy = (ddpy<<1) - dddpy;
1055+ dpx = (dpx<<2) - (ddpx>>1);
1056+ dpy = (dpy<<2) - (ddpy>>1);
1057+ count <<=1;
1058+ decStepBnd <<=3;
1059+ incStepBnd <<=3;
1060+ px <<=3;
1061+ py <<=3;
1062+ shift += 3;
1063+ }
1064+
1065+ /* Perform increasing step in 2 times if necessary.
1066+ * Note: we could do it only in even steps
1067+ */
1068+
1069+ while ((count & 1) == 0 && shift > DF_CUB_SHIFT &&
1070+ Math.abs(dpx) <= incStepBnd &&
1071+ Math.abs(dpy) <= incStepBnd) {
1072+ dpx = (dpx>>2) + (ddpx>>3);
1073+ dpy = (dpy>>2) + (ddpy>>3);
1074+ ddpx = (ddpx + dddpx)>>1;
1075+ ddpy = (ddpy + dddpy)>>1;
1076+ count >>=1;
1077+ decStepBnd >>=3;
1078+ incStepBnd >>=3;
1079+ px >>=3;
1080+ py >>=3;
1081+ shift -= 3;
1082+ }
1083+
1084+ count--;
1085+
1086+ /* Performing one step less than necessary and use actual (xe,ye)
1087+ * curve's endpoint instead of calculated. This prevent us from
1088+ * running above the curve endpoint due to the accumulated errors
1089+ * during the iterations.
1090+ */
1091+ if (count > 0) {
1092+ px += dpx;
1093+ py += dpy;
1094+
1095+ dpx += ddpx;
1096+ dpy += ddpy;
1097+ ddpx += dddpx;
1098+ ddpy += dddpy;
1099+
1100+ x1 = x2;
1101+ y1 = y2;
1102+
1103+ x2 = x0w + (px >> shift);
1104+ y2 = y0w + (py >> shift);
1105+
1106+ /* Checking that we are not running out of the endpoint and
1107+ * bounding violating coordinate. The check is pretty simple
1108+ * because the curve passed to the DrawCubic already splitted
1109+ * into the monotonic in X and Y pieces
1110+ */
1111+
1112+ /* Bounding x2 by xe */
1113+ if (((xe-x2)^dx) < 0) {
1114+ x2 = xe;
1115+ }
1116+
1117+ /* Bounding y2 by ye */
1118+ if (((ye-y2)^dy) < 0) {
1119+ y2 = ye;
1120+ }
1121+
1122+ hnd.processFixedLine(x1, y1, x2, y2, pixelInfo, checkBounds,
1123+ false);
1124+ } else {
1125+ hnd.processFixedLine(x2, y2, xe, ye, pixelInfo, checkBounds,
1126+ false);
1127+ }
1128+ }
1129+ }
1130+
1131+ /*
1132+ * Checking size of the cubic curves and split them if necessary.
1133+ * Calling DrawMonotonicCubic for the curves of the appropriate size.
1134+ * Note: coords array could be changed
1135+ */
1136+ private static void ProcessMonotonicCubic(ProcessHandler hnd,
1137+ float[] coords,
1138+ int[] pixelInfo) {
1139+
1140+ float[] coords1 = new float[8];
1141+ float tx, ty;
1142+ float xMin, xMax;
1143+ float yMin, yMax;
1144+
1145+ xMin = xMax = coords[0];
1146+ yMin = yMax = coords[1];
1147+
1148+ for (int i = 2; i < 8; i += 2) {
1149+ xMin = (xMin > coords[i])? coords[i] : xMin;
1150+ xMax = (xMax < coords[i])? coords[i] : xMax;
1151+ yMin = (yMin > coords[i + 1])? coords[i + 1] : yMin;
1152+ yMax = (yMax < coords[i + 1])? coords[i + 1] : yMax;
1153+ }
1154+
1155+ if (hnd.clipMode == PH_MODE_DRAW_CLIP) {
1156+ /* In case of drawing we could just skip curves which are
1157+ * completely out of bounds
1158+ */
1159+ if (hnd.dhnd.xMaxf < xMin || hnd.dhnd.xMinf > xMax ||
1160+ hnd.dhnd.yMaxf < yMin || hnd.dhnd.yMinf > yMax) {
1161+ return;
1162+ }
1163+ } else {
1164+
1165+ /* In case of filling we could skip curves which are above,
1166+ * below and behind the right boundary of the visible area
1167+ */
1168+
1169+ if (hnd.dhnd.yMaxf < yMin || hnd.dhnd.yMinf > yMax ||
1170+ hnd.dhnd.xMaxf < xMin)
1171+ {
1172+ return;
1173+ }
1174+
1175+ /* We could clamp x coordinates to the corresponding boundary
1176+ * if the curve is completely behind the left one
1177+ */
1178+
1179+ if (hnd.dhnd.xMinf > xMax) {
1180+ coords[0] = coords[2] = coords[4] = coords[6] =
1181+ hnd.dhnd.xMinf;
1182+ }
1183+ }
1184+
1185+ if (xMax - xMin > MAX_CUB_SIZE || yMax - yMin > MAX_CUB_SIZE) {
1186+ coords1[6] = coords[6];
1187+ coords1[7] = coords[7];
1188+ coords1[4] = (coords[4] + coords[6])/2.0f;
1189+ coords1[5] = (coords[5] + coords[7])/2.0f;
1190+ tx = (coords[2] + coords[4])/2.0f;
1191+ ty = (coords[3] + coords[5])/2.0f;
1192+ coords1[2] = (tx + coords1[4])/2.0f;
1193+ coords1[3] = (ty + coords1[5])/2.0f;
1194+ coords[2] = (coords[0] + coords[2])/2.0f;
1195+ coords[3] = (coords[1] + coords[3])/2.0f;
1196+ coords[4] = (coords[2] + tx)/2.0f;
1197+ coords[5] = (coords[3] + ty)/2.0f;
1198+ coords[6]=coords1[0]=(coords[4] + coords1[2])/2.0f;
1199+ coords[7]=coords1[1]=(coords[5] + coords1[3])/2.0f;
1200+
1201+ ProcessMonotonicCubic(hnd, coords, pixelInfo);
1202+
1203+ ProcessMonotonicCubic(hnd, coords1, pixelInfo);
1204+ } else {
1205+ DrawMonotonicCubic(hnd, coords,
1206+ /* Set checkBounds parameter if curve intersects
1207+ * boundary of the visible area. We know that
1208+ * the curve is visible, so the check is pretty
1209+ * simple
1210+ */
1211+ hnd.dhnd.xMinf > xMin ||
1212+ hnd.dhnd.xMaxf < xMax ||
1213+ hnd.dhnd.yMinf > yMin ||
1214+ hnd.dhnd.yMaxf < yMax,
1215+ pixelInfo);
1216+ }
1217+ }
1218+
1219+ /*
1220+ * Split cubic curve into monotonic in X and Y parts. Calling
1221+ * ProcessMonotonicCubic for each monotonic piece of the curve.
1222+ *
1223+ * Note: coords array could be changed
1224+ */
1225+ private static void ProcessCubic(ProcessHandler hnd,
1226+ float[] coords,
1227+ int[] pixelInfo) {
1228+ /* Temporary array for holding parameters corresponding to the extreme
1229+ * in X and Y points
1230+ */
1231+ double params[] = new double[4];
1232+ double eqn[] = new double[3];
1233+ double res[] = new double[2];
1234+ int cnt = 0;
1235+
1236+ /* Simple check for monotonicity in X before searching for the extreme
1237+ * points of the X(t) function. We first check if the curve is
1238+ * monotonic in X by seeing if all of the X coordinates are strongly
1239+ * ordered.
1240+ */
1241+ if ((coords[0] > coords[2] || coords[2] > coords[4] ||
1242+ coords[4] > coords[6]) &&
1243+ (coords[0] < coords[2] || coords[2] < coords[4] ||
1244+ coords[4] < coords[6]))
1245+ {
1246+ /* Searching for extreme points of the X(t) function by solving
1247+ * dX(t)
1248+ * ---- = 0 equation
1249+ * dt
1250+ */
1251+ eqn[2] = -coords[0] + 3*coords[2] - 3*coords[4] + coords[6];
1252+ eqn[1] = 2*(coords[0] - 2*coords[2] + coords[4]);
1253+ eqn[0] = -coords[0] + coords[2];
1254+
1255+ int nr = QuadCurve2D.solveQuadratic(eqn, res);
1256+
1257+ /* Following code also correctly works in degenerate case of
1258+ * the quadratic equation (nr = -1) because we do not need
1259+ * splitting in this case.
1260+ */
1261+ for (int i = 0; i < nr; i++) {
1262+ if (res[i] > 0 && res[i] < 1) {
1263+ params[cnt++] = res[i];
1264+ }
1265+ }
1266+ }
1267+
1268+ /* Simple check for monotonicity in Y before searching for the extreme
1269+ * points of the Y(t) function. We first check if the curve is
1270+ * monotonic in Y by seeing if all of the Y coordinates are strongly
1271+ * ordered.
1272+ */
1273+ if ((coords[1] > coords[3] || coords[3] > coords[5] ||
1274+ coords[5] > coords[7]) &&
1275+ (coords[1] < coords[3] || coords[3] < coords[5] ||
1276+ coords[5] < coords[7]))
1277+ {
1278+ /* Searching for extreme points of the Y(t) function by solving
1279+ * dY(t)
1280+ * ----- = 0 equation
1281+ * dt
1282+ */
1283+ eqn[2] = -coords[1] + 3*coords[3] - 3*coords[5] + coords[7];
1284+ eqn[1] = 2*(coords[1] - 2*coords[3] + coords[5]);
1285+ eqn[0] = -coords[1] + coords[3];
1286+
1287+ int nr = QuadCurve2D.solveQuadratic(eqn, res);
1288+
1289+ /* Following code also correctly works in degenerate case of
1290+ * the quadratic equation (nr = -1) because we do not need
1291+ * splitting in this case.
1292+ */
1293+ for (int i = 0; i < nr; i++) {
1294+ if (res[i] > 0 && res[i] < 1) {
1295+ params[cnt++] = res[i];
1296+ }
1297+ }
1298+ }
1299+
1300+ if (cnt > 0) {
1301+ /* Sorting parameter values corresponding to the extreme points
1302+ * of the curve
1303+ */
1304+ Arrays.sort(params, 0, cnt);
1305+
1306+ /* Processing obtained monotonic parts */
1307+ ProcessFirstMonotonicPartOfCubic(hnd, coords, pixelInfo,
1308+ (float)params[0]);
1309+ for (int i = 1; i < cnt; i++) {
1310+ double param = params[i] - params[i-1];
1311+ if (param > 0) {
1312+ ProcessFirstMonotonicPartOfCubic(hnd, coords, pixelInfo,
1313+ /* Scale parameter to match with rest of the curve */
1314+ (float)(param/(1.0 - params[i - 1])));
1315+ }
1316+ }
1317+ }
1318+
1319+ ProcessMonotonicCubic(hnd,coords,pixelInfo);
1320+ }
1321+
1322+ /*
1323+ * Bite the piece of the cubic curve from start point till the point
1324+ * corresponding to the specified parameter then call ProcessCubic for the
1325+ * bitten part.
1326+ * Note: coords array will be changed
1327+ */
1328+ private static void ProcessFirstMonotonicPartOfCubic(ProcessHandler hnd,
1329+ float[] coords,
1330+ int[] pixelInfo,
1331+ float t)
1332+ {
1333+ float[] coords1 = new float[8];
1334+ float tx, ty;
1335+
1336+ coords1[0] = coords[0];
1337+ coords1[1] = coords[1];
1338+ tx = coords[2] + t*(coords[4] - coords[2]);
1339+ ty = coords[3] + t*(coords[5] - coords[3]);
1340+ coords1[2] = coords[0] + t*(coords[2] - coords[0]);
1341+ coords1[3] = coords[1] + t*(coords[3] - coords[1]);
1342+ coords1[4] = coords1[2] + t*(tx - coords1[2]);
1343+ coords1[5] = coords1[3] + t*(ty - coords1[3]);
1344+ coords[4] = coords[4] + t*(coords[6] - coords[4]);
1345+ coords[5] = coords[5] + t*(coords[7] - coords[5]);
1346+ coords[2] = tx + t*(coords[4] - tx);
1347+ coords[3] = ty + t*(coords[5] - ty);
1348+ coords[0]=coords1[6]=coords1[4] + t*(coords[2] - coords1[4]);
1349+ coords[1]=coords1[7]=coords1[5] + t*(coords[3] - coords1[5]);
1350+
1351+ ProcessMonotonicCubic(hnd, coords1, pixelInfo);
1352+ }
1353+
1354+ /* Note:
1355+ * For more easy reading of the code below each java version of the macros
1356+ * from the ProcessPath.c preceded by the commented origin call
1357+ * containing verbose names of the parameters
1358+ */
1359+ private static void ProcessLine(ProcessHandler hnd, float x1, float y1,
1360+ float x2, float y2, int[] pixelInfo) {
1361+ float xMin, yMin, xMax, yMax;
1362+ int X1, Y1, X2, Y2, X3, Y3, res;
1363+ boolean clipped = false;
1364+ float x3,y3;
1365+ float c[] = new float[]{x1, y1, x2, y2, 0, 0};
1366+
1367+ boolean lastClipped;
1368+
1369+ xMin = hnd.dhnd.xMinf;
1370+ yMin = hnd.dhnd.yMinf;
1371+ xMax = hnd.dhnd.xMaxf;
1372+ yMax = hnd.dhnd.yMaxf;
1373+
1374+ //
1375+ // TESTANDCLIP(yMin, yMax, y1, x1, y2, x2, res);
1376+ //
1377+ res = TESTANDCLIP(yMin, yMax, c, 1, 0, 3, 2);
1378+ if (res == CRES_INVISIBLE) return;
1379+ clipped = IS_CLIPPED(res);
1380+ //
1381+ // TESTANDCLIP(yMin, yMax, y2, x2, y1, x1, res);
1382+ //
1383+ res = TESTANDCLIP(yMin, yMax, c, 3, 2, 1, 0);
1384+ if (res == CRES_INVISIBLE) return;
1385+ lastClipped = IS_CLIPPED(res);
1386+ clipped = clipped || lastClipped;
1387+
1388+ if (hnd.clipMode == PH_MODE_DRAW_CLIP) {
1389+ //
1390+ // TESTANDCLIP(xMin, xMax, x1, y1, x2, y2, res);
1391+ //
1392+ res = TESTANDCLIP(xMin, xMax, c, 0, 1, 2, 3);
1393+ if (res == CRES_INVISIBLE) return;
1394+ clipped = clipped || IS_CLIPPED(res);
1395+ //
1396+ // TESTANDCLIP(xMin, xMax, x2, y2, x1, y1, res);
1397+ //
1398+ res = TESTANDCLIP(xMin, xMax, c, 2, 3, 0, 1);
1399+ if (res == CRES_INVISIBLE) return;
1400+ lastClipped = lastClipped || IS_CLIPPED(res);
1401+ clipped = clipped || lastClipped;
1402+ X1 = (int)(c[0]*MDP_MULT);
1403+ Y1 = (int)(c[1]*MDP_MULT);
1404+ X2 = (int)(c[2]*MDP_MULT);
1405+ Y2 = (int)(c[3]*MDP_MULT);
1406+
1407+ hnd.processFixedLine(X1, Y1, X2, Y2, pixelInfo,
1408+ clipped, /* enable boundary checking in
1409+ case of clipping to avoid
1410+ entering out of bounds which
1411+ could happens during rounding
1412+ */
1413+ lastClipped /* Notify pProcessFixedLine
1414+ that
1415+ this is the end of the
1416+ subpath (because of exiting
1417+ out of boundaries)
1418+ */
1419+ );
1420+ } else {
1421+ /* Clamping starting from first vertex of the the processed
1422+ * segment
1423+ *
1424+ * CLIPCLAMP(xMin, xMax, x1, y1, x2, y2, x3, y3, res);
1425+ */
1426+ res = CLIPCLAMP(xMin, xMax, c, 0, 1, 2, 3, 4, 5);
1427+ X1 = (int)(c[0]*MDP_MULT);
1428+ Y1 = (int)(c[1]*MDP_MULT);
1429+
1430+ /* Clamping only by left boundary */
1431+ if (res == CRES_MIN_CLIPPED) {
1432+ X3 = (int)(c[4]*MDP_MULT);
1433+ Y3 = (int)(c[5]*MDP_MULT);
1434+ hnd.processFixedLine(X3, Y3, X1, Y1, pixelInfo,
1435+ false, lastClipped);
1436+
1437+ } else if (res == CRES_INVISIBLE) {
1438+ return;
1439+ }
1440+
1441+ /* Clamping starting from last vertex of the the processed
1442+ * segment
1443+ *
1444+ * CLIPCLAMP(xMin, xMax, x2, y2, x1, y1, x3, y3, res);
1445+ */
1446+ res = CLIPCLAMP(xMin, xMax, c, 2, 3, 0, 1, 4, 5);
1447+
1448+ /* Checking if there was a clip by right boundary */
1449+ lastClipped = lastClipped || (res == CRES_MAX_CLIPPED);
1450+
1451+ X2 = (int)(c[2]*MDP_MULT);
1452+ Y2 = (int)(c[3]*MDP_MULT);
1453+ hnd.processFixedLine(X1, Y1, X2, Y2, pixelInfo,
1454+ false, lastClipped);
1455+
1456+ /* Clamping only by left boundary */
1457+ if (res == CRES_MIN_CLIPPED) {
1458+ X3 = (int)(c[4]*MDP_MULT);
1459+ Y3 = (int)(c[5]*MDP_MULT);
1460+ hnd.processFixedLine(X2, Y2, X3, Y3, pixelInfo,
1461+ false, lastClipped);
1462+ }
1463+ }
1464+ }
1465+
1466+ private static boolean doProcessPath(ProcessHandler hnd,
1467+ Path2D.Float p2df,
1468+ float transXf, float transYf) {
1469+ float coords[] = new float[8];
1470+ float tCoords[] = new float[8];
1471+ float closeCoord[] = new float[] {0.0f, 0.0f};
1472+ float firstCoord[] = new float[2];
1473+ int pixelInfo[] = new int[5];
1474+ boolean subpathStarted = false;
1475+ boolean skip = false;
1476+ float lastX, lastY;
1477+ pixelInfo[0] = 0;
1478+
1479+ /* Adjusting boundaries to the capabilities of the
1480+ * ProcessPath code
1481+ */
1482+ hnd.dhnd.adjustBounds(LOWER_OUT_BND, LOWER_OUT_BND,
1483+ UPPER_OUT_BND, UPPER_OUT_BND);
1484+
1485+ /* Adding support of the KEY_STROKE_CONTROL rendering hint.
1486+ * Now we are supporting two modes: "pixels at centers" and
1487+ * "pixels at corners".
1488+ * First one is disabled by default but could be enabled by setting
1489+ * VALUE_STROKE_PURE to the rendering hint. It means that pixel at the
1490+ * screen (x,y) has (x + 0.5, y + 0.5) float coordinates.
1491+ *
1492+ * Second one is enabled by default and means straightforward mapping
1493+ * (x,y) --> (x,y)
1494+ */
1495+ if (hnd.dhnd.strokeControl == SunHints.INTVAL_STROKE_PURE) {
1496+ closeCoord[0] = -0.5f;
1497+ closeCoord[1] = -0.5f;
1498+ transXf -= 0.5;
1499+ transYf -= 0.5;
1500+ }
1501+
1502+ PathIterator pi = p2df.getPathIterator(null);
1503+
1504+ while (!pi.isDone()) {
1505+ switch (pi.currentSegment(coords)) {
1506+ case PathIterator.SEG_MOVETO:
1507+ /* Performing closing of the unclosed segments */
1508+ if (subpathStarted && !skip) {
1509+ if (hnd.clipMode == PH_MODE_FILL_CLIP) {
1510+ if (tCoords[0] != closeCoord[0] ||
1511+ tCoords[1] != closeCoord[1])
1512+ {
1513+ ProcessLine(hnd, tCoords[0], tCoords[1],
1514+ closeCoord[0], closeCoord[1],
1515+ pixelInfo);
1516+ }
1517+ }
1518+ hnd.processEndSubPath();
1519+ }
1520+
1521+ tCoords[0] = coords[0] + transXf;
1522+ tCoords[1] = coords[1] + transYf;
1523+
1524+ /* Checking SEG_MOVETO coordinates if they are out of the
1525+ * [LOWER_BND, UPPER_BND] range. This check also handles
1526+ * NaN and Infinity values. Skipping next path segment in
1527+ * case of invalid data.
1528+ */
1529+
1530+ if (tCoords[0] < UPPER_BND &&
1531+ tCoords[0] > LOWER_BND &&
1532+ tCoords[1] < UPPER_BND &&
1533+ tCoords[1] > LOWER_BND)
1534+ {
1535+ subpathStarted = true;
1536+ skip = false;
1537+ closeCoord[0] = tCoords[0];
1538+ closeCoord[1] = tCoords[1];
1539+ } else {
1540+ skip = true;
1541+ }
1542+ pixelInfo[0] = 0;
1543+ break;
1544+ case PathIterator.SEG_LINETO:
1545+ lastX = tCoords[2] = coords[0] + transXf;
1546+ lastY = tCoords[3] = coords[1] + transYf;
1547+
1548+ /* Checking SEG_LINETO coordinates if they are out of the
1549+ * [LOWER_BND, UPPER_BND] range. This check also handles
1550+ * NaN and Infinity values. Ignoring current path segment
1551+ * in case of invalid data. If segment is skipped its
1552+ * endpoint (if valid) is used to begin new subpath.
1553+ */
1554+
1555+ if (lastX < UPPER_BND &&
1556+ lastX > LOWER_BND &&
1557+ lastY < UPPER_BND &&
1558+ lastY > LOWER_BND)
1559+ {
1560+ if (skip) {
1561+ tCoords[0] = closeCoord[0] = lastX;
1562+ tCoords[1] = closeCoord[1] = lastY;
1563+ subpathStarted = true;
1564+ skip = false;
1565+ } else {
1566+ ProcessLine(hnd, tCoords[0], tCoords[1],
1567+ tCoords[2], tCoords[3], pixelInfo);
1568+ tCoords[0] = lastX;
1569+ tCoords[1] = lastY;
1570+ }
1571+ }
1572+ break;
1573+ case PathIterator.SEG_QUADTO:
1574+ tCoords[2] = coords[0] + transXf;
1575+ tCoords[3] = coords[1] + transYf;
1576+ lastX = tCoords[4] = coords[2] + transXf;
1577+ lastY = tCoords[5] = coords[3] + transYf;
1578+
1579+ /* Checking SEG_QUADTO coordinates if they are out of the
1580+ * [LOWER_BND, UPPER_BND] range. This check also handles
1581+ * NaN and Infinity values. Ignoring current path segment
1582+ * in case of invalid endpoints's data. Equivalent to
1583+ * the SEG_LINETO if endpoint coordinates are valid but
1584+ * there are invalid data among other coordinates
1585+ */
1586+
1587+ if (lastX < UPPER_BND &&
1588+ lastX > LOWER_BND &&
1589+ lastY < UPPER_BND &&
1590+ lastY > LOWER_BND)
1591+ {
1592+ if (skip) {
1593+ tCoords[0] = closeCoord[0] = lastX;
1594+ tCoords[1] = closeCoord[1] = lastY;
1595+ subpathStarted = true;
1596+ skip = false;
1597+ } else {
1598+ if (tCoords[2] < UPPER_BND &&
1599+ tCoords[2] > LOWER_BND &&
1600+ tCoords[3] < UPPER_BND &&
1601+ tCoords[3] > LOWER_BND)
1602+ {
1603+ ProcessQuad(hnd, tCoords, pixelInfo);
1604+ } else {
1605+ ProcessLine(hnd, tCoords[0], tCoords[1],
1606+ tCoords[4], tCoords[5],
1607+ pixelInfo);
1608+ }
1609+ tCoords[0] = lastX;
1610+ tCoords[1] = lastY;
1611+ }
1612+ }
1613+ break;
1614+ case PathIterator.SEG_CUBICTO:
1615+ tCoords[2] = coords[0] + transXf;
1616+ tCoords[3] = coords[1] + transYf;
1617+ tCoords[4] = coords[2] + transXf;
1618+ tCoords[5] = coords[3] + transYf;
1619+ lastX = tCoords[6] = coords[4] + transXf;
1620+ lastY = tCoords[7] = coords[5] + transYf;
1621+
1622+ /* Checking SEG_CUBICTO coordinates if they are out of the
1623+ * [LOWER_BND, UPPER_BND] range. This check also handles
1624+ * NaN and Infinity values. Ignoring current path segment
1625+ * in case of invalid endpoints's data. Equivalent to
1626+ * the SEG_LINETO if endpoint coordinates are valid but
1627+ * there are invalid data among other coordinates
1628+ */
1629+
1630+ if (lastX < UPPER_BND &&
1631+ lastX > LOWER_BND &&
1632+ lastY < UPPER_BND &&
1633+ lastY > LOWER_BND)
1634+ {
1635+ if (skip) {
1636+ tCoords[0] = closeCoord[0] = tCoords[6];
1637+ tCoords[1] = closeCoord[1] = tCoords[7];
1638+ subpathStarted = true;
1639+ skip = false;
1640+ } else {
1641+ if (tCoords[2] < UPPER_BND &&
1642+ tCoords[2] > LOWER_BND &&
1643+ tCoords[3] < UPPER_BND &&
1644+ tCoords[3] > LOWER_BND &&
1645+ tCoords[4] < UPPER_BND &&
1646+ tCoords[4] > LOWER_BND &&
1647+ tCoords[5] < UPPER_BND &&
1648+ tCoords[5] > LOWER_BND)
1649+ {
1650+ ProcessCubic(hnd, tCoords, pixelInfo);
1651+ } else {
1652+ ProcessLine(hnd, tCoords[0], tCoords[1],
1653+ tCoords[6], tCoords[7],
1654+ pixelInfo);
1655+ }
1656+ tCoords[0] = lastX;
1657+ tCoords[1] = lastY;
1658+ }
1659+ }
1660+ break;
1661+ case PathIterator.SEG_CLOSE:
1662+ if (subpathStarted && !skip) {
1663+ skip = false;
1664+ if (tCoords[0] != closeCoord[0] ||
1665+ tCoords[1] != closeCoord[1])
1666+ {
1667+ ProcessLine(hnd, tCoords[0], tCoords[1],
1668+ closeCoord[0], closeCoord[1],
1669+ pixelInfo);
1670+
1671+ /* Storing last path's point for using in following
1672+ * segments without initial moveTo
1673+ */
1674+ tCoords[0] = closeCoord[0];
1675+ tCoords[1] = closeCoord[1];
1676+ }
1677+ hnd.processEndSubPath();
1678+ }
1679+ break;
1680+ }
1681+ pi.next();
1682+ }
1683+
1684+ /* Performing closing of the unclosed segments */
1685+ if (subpathStarted & !skip) {
1686+ if (hnd.clipMode == PH_MODE_FILL_CLIP) {
1687+ if (tCoords[0] != closeCoord[0] ||
1688+ tCoords[1] != closeCoord[1])
1689+ {
1690+ ProcessLine(hnd, tCoords[0], tCoords[1],
1691+ closeCoord[0], closeCoord[1],
1692+ pixelInfo);
1693+ }
1694+ }
1695+ hnd.processEndSubPath();
1696+ }
1697+ return true;
1698+ }
1699+
1700+ private static class Point {
1701+ public int x;
1702+ public int y;
1703+ public boolean lastPoint;
1704+ public Point prev;
1705+ public Point next;
1706+ public Point nextByY;
1707+ public Edge edge;
1708+ public Point(int x, int y, boolean lastPoint) {
1709+ this.x = x;
1710+ this.y = y;
1711+ this.lastPoint = lastPoint;
1712+ }
1713+ };
1714+
1715+ private static class Edge {
1716+ int x;
1717+ int dx;
1718+ Point p;
1719+ int dir;
1720+ Edge prev;
1721+ Edge next;
1722+
1723+ public Edge(Point p, int x, int dx, int dir) {
1724+ this.p = p;
1725+ this.x = x;
1726+ this.dx = dx;
1727+ this.dir = dir;
1728+ }
1729+ };
1730+
1731+ /* Size of the default buffer in the FillData structure. This buffer is
1732+ * replaced with heap allocated in case of large paths.
1733+ */
1734+ private static final int DF_MAX_POINT = 256;
1735+
1736+ /* Following class accumulates points of the non-continuous flattened
1737+ * general path during iteration through the origin path's segments . The
1738+ * end of the each subpath is marked as lastPoint flag set at the last
1739+ * point
1740+ */
1741+ private static class FillData {
1742+ List<Point> plgPnts;
1743+ public int plgYMin;
1744+ public int plgYMax;
1745+
1746+ public FillData() {
1747+ plgPnts = new Vector<Point>(DF_MAX_POINT);
1748+ }
1749+
1750+ public void addPoint(int x, int y, boolean lastPoint) {
1751+ if (plgPnts.size() == 0) {
1752+ plgYMin = plgYMax = y;
1753+ } else {
1754+ plgYMin = (plgYMin > y)?y:plgYMin;
1755+ plgYMax = (plgYMax < y)?y:plgYMax;
1756+ }
1757+
1758+ plgPnts.add(new Point(x, y, lastPoint));
1759+ }
1760+
1761+ public boolean isEmpty() {
1762+ return plgPnts.size() == 0;
1763+ }
1764+
1765+ public boolean isEnded() {
1766+ return plgPnts.get(plgPnts.size() - 1).lastPoint;
1767+ }
1768+
1769+ public boolean setEnded() {
1770+ return plgPnts.get(plgPnts.size() - 1).lastPoint = true;
1771+ }
1772+ }
1773+
1774+ private static class ActiveEdgeList {
1775+ Edge head;
1776+
1777+ public boolean isEmpty() {
1778+ return (head == null);
1779+ }
1780+
1781+ public void insert(Point pnt, int cy) {
1782+ Point np = pnt.next;
1783+ int X1 = pnt.x, Y1 = pnt.y;
1784+ int X2 = np.x, Y2 = np.y;
1785+ Edge ne;
1786+ if (Y1 == Y2) {
1787+ /* Skipping horizontal segments */
1788+ return;
1789+ } else {
1790+ int dX = X2 - X1;
1791+ int dY = Y2 - Y1;
1792+ int stepx, x0, dy, dir;
1793+
1794+ if (Y1 < Y2) {
1795+ x0 = X1;
1796+ dy = cy - Y1;
1797+ dir = -1;
1798+ } else { // (Y1 > Y2)
1799+ x0 = X2;
1800+ dy = cy - Y2;
1801+ dir = 1;
1802+ }
1803+
1804+ /* We need to worry only about dX because dY is in denominator
1805+ * and abs(dy) < MDP_MULT (cy is a first scanline of the scan
1806+ * converted segment and we subtract y coordinate of the
1807+ * nearest segment's end from it to obtain dy)
1808+ */
1809+ if (dX > CALC_UBND || dX < CALC_LBND) {
1810+ stepx = (int)((((double)dX)*MDP_MULT)/dY);
1811+ x0 = x0 + (int)((((double)dX)*dy)/dY);
1812+ } else {
1813+ stepx = (dX<<MDP_PREC)/dY;
1814+ x0 += (dX*dy)/dY;
1815+ }
1816+
1817+ ne = new Edge(pnt, x0, stepx, dir);
1818+ }
1819+
1820+ ne.next = head;
1821+ ne.prev = null;
1822+ if (head != null) {
1823+ head.prev = ne;
1824+ }
1825+ head = pnt.edge = ne;
1826+ }
1827+
1828+ public void delete(Edge e) {
1829+ Edge prevp = e.prev;
1830+ Edge nextp = e.next;
1831+ if (prevp != null) {
1832+ prevp.next = nextp;
1833+ } else {
1834+ head = nextp;
1835+ }
1836+ if (nextp != null) {
1837+ nextp.prev = prevp;
1838+ }
1839+ }
1840+
1841+ /**
1842+ * Bubble sorting in the ascending order of the linked list. This
1843+ * implementation stops processing the list if there were no changes
1844+ * during the previous pass.
1845+ *
1846+ * We could not use O(N) Radix sort here because in most cases list of
1847+ * edges almost sorted. So, bubble sort (O(N^2)) is working much
1848+ * better. Note, in case of array of edges Shell sort is more
1849+ * efficient.
1850+ */
1851+ public void sort() {
1852+ Edge p, q, r, s = null, temp;
1853+ boolean wasSwap = true;
1854+
1855+ // r precedes p and s points to the node up to which
1856+ // comparisons are to be made
1857+ while (s != head.next && wasSwap) {
1858+ r = p = head;
1859+ q = p.next;
1860+ wasSwap = false;
1861+ while (p != s) {
1862+ if (p.x >= q.x) {
1863+ wasSwap = true;
1864+ if (p == head) {
1865+ temp = q.next;
1866+ q.next = p;
1867+ p.next = temp;
1868+ head = q;
1869+ r = q;
1870+ } else {
1871+ temp = q.next;
1872+ q.next = p;
1873+ p.next = temp;
1874+ r.next = q;
1875+ r = q;
1876+ }
1877+ } else {
1878+ r = p;
1879+ p = p.next;
1880+ }
1881+ q = p.next;
1882+ if (q == s) s = p;
1883+ }
1884+ }
1885+
1886+ // correction of the back links in the double linked edge list
1887+ p = head;
1888+ q = null;
1889+ while (p != null) {
1890+ p.prev = q;
1891+ q = p;
1892+ p = p.next;
1893+ }
1894+ }
1895+ }
1896+
1897+ private static void FillPolygon(FillProcessHandler hnd,
1898+ int fillRule) {
1899+ int k, y, n;
1900+ boolean drawing;
1901+ Edge active;
1902+ int rightBnd = hnd.dhnd.xMax - 1;
1903+ FillData fd = hnd.fd;
1904+ int yMin = fd.plgYMin;
1905+ int yMax = fd.plgYMax;
1906+ int hashSize = ((yMax - yMin)>>MDP_PREC) + 4;
1907+
1908+ /* Because of support of the KEY_STROKE_CONTROL hint we are performing
1909+ * shift of the coordinates at the higher level
1910+ */
1911+ int hashOffset = ((yMin - 1) & MDP_W_MASK);
1912+
1913+ /* Winding counter */
1914+ int counter;
1915+
1916+ /* Calculating mask to be applied to the winding counter */
1917+ int counterMask =
1918+ (fillRule == PathIterator.WIND_NON_ZERO)? -1:1;
1919+
1920+ int pntOffset;
1921+ List<Point> pnts = fd.plgPnts;
1922+ n = pnts.size();
1923+
1924+ if (n <=1) return;
1925+
1926+ Point[] yHash = new Point[hashSize];
1927+
1928+ /* Creating double linked list (prev, next links) describing path order
1929+ * and hash table with points which fall between scanlines. nextByY
1930+ * link is used for the points which are between same scanlines.
1931+ * Scanlines are passed through the centers of the pixels.
1932+ */
1933+ Point curpt = pnts.get(0);
1934+ curpt.prev = null;
1935+ for (int i = 0; i < n - 1; i++) {
1936+ curpt = pnts.get(i);
1937+ Point nextpt = pnts.get(i + 1);
1938+ int curHashInd = (curpt.y - hashOffset - 1) >> MDP_PREC;
1939+ curpt.nextByY = yHash[curHashInd];
1940+ yHash[curHashInd] = curpt;
1941+ curpt.next = nextpt;
1942+ nextpt.prev = curpt;
1943+ }
1944+
1945+ Point ept = pnts.get(n - 1);
1946+ int curHashInd = (ept.y - hashOffset - 1) >> MDP_PREC;
1947+ ept.nextByY = yHash[curHashInd];
1948+ yHash[curHashInd] = ept;
1949+
1950+ ActiveEdgeList activeList = new ActiveEdgeList();
1951+
1952+ for (y=hashOffset + MDP_MULT,k = 0;
1953+ y<=yMax && k < hashSize; y += MDP_MULT, k++)
1954+ {
1955+ for(Point pt = yHash[k];pt != null; pt=pt.nextByY) {
1956+ /* pt.y should be inside hashed interval
1957+ * assert(y-MDP_MULT <= pt.y && pt.y < y);
1958+ */
1959+ if (pt.prev != null && !pt.prev.lastPoint) {
1960+ if (pt.prev.edge != null && pt.prev.y <= y) {
1961+ activeList.delete(pt.prev.edge);
1962+ pt.prev.edge = null;
1963+ } else if (pt.prev.y > y) {
1964+ activeList.insert(pt.prev, y);
1965+ }
1966+ }
1967+
1968+ if (!pt.lastPoint && pt.next != null) {
1969+ if (pt.edge != null && pt.next.y <= y) {
1970+ activeList.delete(pt.edge);
1971+ pt.edge = null;
1972+ } else if (pt.next.y > y) {
1973+ activeList.insert(pt, y);
1974+ }
1975+ }
1976+ }
1977+
1978+ if (activeList.isEmpty()) continue;
1979+
1980+ activeList.sort();
1981+
1982+ counter = 0;
1983+ drawing = false;
1984+ int xl, xr;
1985+ xl = xr = hnd.dhnd.xMin;
1986+ Edge curEdge = activeList.head;
1987+ while (curEdge != null) {
1988+ counter += curEdge.dir;
1989+ if ((counter & counterMask) != 0 && !drawing) {
1990+ xl = (curEdge.x + MDP_MULT - 1)>>MDP_PREC;
1991+ drawing = true;
1992+ }
1993+
1994+ if ((counter & counterMask) == 0 && drawing) {
1995+ xr = (curEdge.x - 1) >> MDP_PREC;
1996+ if (xl <= xr) {
1997+ hnd.dhnd.drawScanline(xl, xr, y >> MDP_PREC);
1998+ }
1999+ drawing = false;
2000+ }
2001+
2002+ curEdge.x += curEdge.dx;
2003+ curEdge = curEdge.next;
2004+ }
2005+
2006+ /* Performing drawing till the right boundary (for correct
2007+ * rendering shapes clipped at the right side)
2008+ */
2009+ if (drawing && xl <= rightBnd) {
2010+
2011+ /* Support of the strokeHint was added into the
2012+ * draw and fill methods of the sun.java2d.pipe.LoopPipe
2013+ */
2014+ hnd.dhnd.drawScanline(xl, rightBnd, y >> MDP_PREC);
2015+ }
2016+ }
2017+ }
2018+
2019+ private static class FillProcessHandler extends ProcessHandler {
2020+
2021+ FillData fd;
2022+
2023+ /* Note: For more easy reading of the code below each java version of
2024+ * the macros from the ProcessPath.c preceded by the commented
2025+ * origin call containing verbose names of the parameters
2026+ */
2027+ public void processFixedLine(int x1, int y1, int x2, int y2,
2028+ int[] pixelInfo, boolean checkBounds,
2029+ boolean endSubPath)
2030+ {
2031+ int outXMin, outXMax, outYMin, outYMax;
2032+ int res;
2033+
2034+ /* There is no need to round line coordinates to the forward
2035+ * differencing precision anymore. Such a rounding was used for
2036+ * preventing the curve go out the endpoint (this sometimes does
2037+ * not help). The problem was fixed in the forward differencing
2038+ * loops.
2039+ */
2040+ if (checkBounds) {
2041+ boolean lastClipped;
2042+
2043+ /* This function is used only for filling shapes, so there is no
2044+ * check for the type of clipping
2045+ */
2046+ int c[] = new int[]{x1, y1, x2, y2, 0, 0};
2047+ outXMin = (int)(dhnd.xMinf * MDP_MULT);
2048+ outXMax = (int)(dhnd.xMaxf * MDP_MULT);
2049+ outYMin = (int)(dhnd.yMinf * MDP_MULT);
2050+ outYMax = (int)(dhnd.yMaxf * MDP_MULT);
2051+
2052+ /*
2053+ * TESTANDCLIP(outYMin, outYMax, y1, x1, y2, x2, res);
2054+ */
2055+ res = TESTANDCLIP(outYMin, outYMax, c, 1, 0, 3, 2);
2056+ if (res == CRES_INVISIBLE) return;
2057+
2058+ /*
2059+ * TESTANDCLIP(outYMin, outYMax, y2, x2, y1, x1, res);
2060+ */
2061+ res = TESTANDCLIP(outYMin, outYMax, c, 3, 2, 1, 0);
2062+ if (res == CRES_INVISIBLE) return;
2063+ lastClipped = IS_CLIPPED(res);
2064+
2065+ /* Clamping starting from first vertex of the the processed
2066+ * segment
2067+ *
2068+ * CLIPCLAMP(outXMin, outXMax, x1, y1, x2, y2, x3, y3, res);
2069+ */
2070+ res = CLIPCLAMP(outXMin, outXMax, c, 0, 1, 2, 3, 4, 5);
2071+
2072+ /* Clamping only by left boundary */
2073+ if (res == CRES_MIN_CLIPPED) {
2074+ processFixedLine(c[4], c[5], c[0], c[1], pixelInfo,
2075+ false, lastClipped);
2076+
2077+ } else if (res == CRES_INVISIBLE) {
2078+ return;
2079+ }
2080+
2081+ /* Clamping starting from last vertex of the the processed
2082+ * segment
2083+ *
2084+ * CLIPCLAMP(outXMin, outXMax, x2, y2, x1, y1, x3, y3, res);
2085+ */
2086+ res = CLIPCLAMP(outXMin, outXMax, c, 2, 3, 0, 1, 4, 5);
2087+
2088+ /* Checking if there was a clip by right boundary */
2089+ lastClipped = lastClipped || (res == CRES_MAX_CLIPPED);
2090+
2091+ processFixedLine(c[0], c[1], c[2], c[3], pixelInfo,
2092+ false, lastClipped);
2093+
2094+ /* Clamping only by left boundary */
2095+ if (res == CRES_MIN_CLIPPED) {
2096+ processFixedLine(c[2], c[3], c[4], c[5], pixelInfo,
2097+ false, lastClipped);
2098+ }
2099+
2100+ return;
2101+ }
2102+
2103+ /* Adding first point of the line only in case of empty or just
2104+ * finished path
2105+ */
2106+ if (fd.isEmpty() || fd.isEnded()) {
2107+ fd.addPoint(x1, y1, false);
2108+ }
2109+
2110+ fd.addPoint(x2, y2, false);
2111+
2112+ if (endSubPath) {
2113+ fd.setEnded();
2114+ }
2115+ }
2116+
2117+ FillProcessHandler(DrawHandler dhnd) {
2118+ super(dhnd, PH_MODE_FILL_CLIP);
2119+ this.fd = new FillData();
2120+ }
2121+
2122+ public void processEndSubPath() {
2123+ if (!fd.isEmpty()) {
2124+ fd.setEnded();
2125+ }
2126+ }
2127+ }
2128+}
java/pkg/sun/java2d/loops/RenderCache$Entry.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/RenderCache.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/RenderCache.java+103−0
@@ -0,0 +1,103 @@
1+/*
2+ * Copyright (c) 1999, 2004, 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+
26+package sun.java2d.loops;
27+
28+public final class RenderCache {
29+ final class Entry {
30+ private SurfaceType src;
31+ private CompositeType comp;
32+ private SurfaceType dst;
33+ private Object value;
34+
35+ public Entry(SurfaceType src,
36+ CompositeType comp,
37+ SurfaceType dst,
38+ Object value)
39+ {
40+ this.src = src;
41+ this.comp = comp;
42+ this.dst = dst;
43+ this.value = value;
44+ }
45+
46+ public boolean matches(SurfaceType src,
47+ CompositeType comp,
48+ SurfaceType dst)
49+ {
50+ // bug 4725045: using equals() causes different SurfaceType
51+ // objects with the same strings to match in the cache, which is
52+ // not the behavior we want. Constrain the match to succeed only
53+ // on object matches instead.
54+ return ((this.src == src) &&
55+ (this.comp == comp) &&
56+ (this.dst == dst));
57+ }
58+
59+ public Object getValue() {
60+ return value;
61+ }
62+ }
63+
64+ private Entry entries[];
65+
66+ public RenderCache(int size) {
67+ entries = new Entry[size];
68+ }
69+
70+ public synchronized Object get(SurfaceType src,
71+ CompositeType comp,
72+ SurfaceType dst)
73+ {
74+ int max = entries.length - 1;
75+ for (int i = max; i >= 0; i--) {
76+ Entry e = entries[i];
77+ if (e == null) {
78+ break;
79+ }
80+ if (e.matches(src, comp, dst)) {
81+ if (i < max - 4) {
82+ System.arraycopy(entries, i+1, entries, i, max - i);
83+ entries[max] = e;
84+ }
85+ return e.getValue();
86+ }
87+ }
88+
89+ return null;
90+ }
91+
92+ public synchronized void put(SurfaceType src,
93+ CompositeType comp,
94+ SurfaceType dst,
95+ Object value)
96+ {
97+ Entry e = new Entry(src, comp, dst, value);
98+
99+ int num = entries.length;
100+ System.arraycopy(entries, 1, entries, 0, num - 1);
101+ entries[num - 1] = e;
102+ }
103+}
java/pkg/sun/java2d/loops/RenderLoops.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/RenderLoops.java+55−0
@@ -0,0 +1,55 @@
1+/*
2+ * Copyright (c) 1999, 2010, 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+
26+package sun.java2d.loops;
27+
28+/*
29+ * This class stores the various loops that are used by the
30+ * standard rendering pipelines. The loops for a given instance
31+ * of this class will all share the same destination type and the
32+ * same supported paint and composite operation.
33+ * Each instance of this class should be shared by all graphics
34+ * objects that render onto the same type of destination with the
35+ * same paint and composite combination to reduce the amount of
36+ * time spent looking up loops appropriate for the current fill
37+ * technique.
38+ */
39+public class RenderLoops {
40+
41+ public static final int primTypeID = GraphicsPrimitive.makePrimTypeID();
42+
43+ public DrawLine drawLineLoop;
44+ public FillRect fillRectLoop;
45+ public DrawRect drawRectLoop;
46+ public DrawPolygons drawPolygonsLoop;
47+ public DrawPath drawPathLoop;
48+ public FillPath fillPathLoop;
49+ public FillSpans fillSpansLoop;
50+ public FillParallelogram fillParallelogramLoop;
51+ public DrawParallelogram drawParallelogramLoop;
52+ public DrawGlyphList drawGlyphListLoop;
53+ public DrawGlyphListAA drawGlyphListAALoop;
54+ public DrawGlyphListLCD drawGlyphListLCDLoop;
55+}
java/pkg/sun/java2d/loops/ScaledBlit$TraceScaledBlit.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/ScaledBlit.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/ScaledBlit.java+156−0
@@ -0,0 +1,156 @@
1+/*
2+ * Copyright (c) 2001, 2004, 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+
26+package sun.java2d.loops;
27+
28+import java.awt.Composite;
29+import java.lang.ref.WeakReference;
30+import sun.java2d.loops.GraphicsPrimitive;
31+import sun.java2d.SurfaceData;
32+import sun.java2d.pipe.Region;
33+
34+/**
35+ * ScaledBlit
36+ * 1) copies rectangle of pixels from one surface to another
37+ * while scaling the pixels to meet the sizes specified
38+ * 2) performs compositing of colors based upon a Composite
39+ * parameter
40+ *
41+ * precise behavior is undefined if the source surface
42+ * and the destination surface are the same surface
43+ * with overlapping regions of pixels
44+ */
45+
46+public class ScaledBlit extends GraphicsPrimitive
47+{
48+ public static final String methodSignature = "ScaledBlit(...)".toString();
49+
50+ public static final int primTypeID = makePrimTypeID();
51+
52+ private static RenderCache blitcache = new RenderCache(20);
53+
54+ public static ScaledBlit locate(SurfaceType srctype,
55+ CompositeType comptype,
56+ SurfaceType dsttype)
57+ {
58+ return (ScaledBlit)
59+ GraphicsPrimitiveMgr.locate(primTypeID,
60+ srctype, comptype, dsttype);
61+ }
62+
63+ public static ScaledBlit getFromCache(SurfaceType src,
64+ CompositeType comp,
65+ SurfaceType dst)
66+ {
67+ Object o = blitcache.get(src, comp, dst);
68+ if (o != null) {
69+ return (ScaledBlit) o;
70+ }
71+ ScaledBlit blit = locate(src, comp, dst);
72+ if (blit == null) {
73+ /*
74+ System.out.println("blit loop not found for:");
75+ System.out.println("src: "+src);
76+ System.out.println("comp: "+comp);
77+ System.out.println("dst: "+dst);
78+ */
79+ } else {
80+ blitcache.put(src, comp, dst, blit);
81+ }
82+ return blit;
83+ }
84+
85+ protected ScaledBlit(SurfaceType srctype,
86+ CompositeType comptype,
87+ SurfaceType dsttype)
88+ {
89+ super(methodSignature, primTypeID, srctype, comptype, dsttype);
90+ }
91+
92+ public ScaledBlit(long pNativePrim,
93+ SurfaceType srctype,
94+ CompositeType comptype,
95+ SurfaceType dsttype)
96+ {
97+ super(pNativePrim, methodSignature, primTypeID,
98+ srctype, comptype, dsttype);
99+ }
100+
101+ public native void Scale(SurfaceData src, SurfaceData dst,
102+ Composite comp, Region clip,
103+ int sx1, int sy1,
104+ int sx2, int sy2,
105+ double dx1, double dy1,
106+ double dx2, double dy2);
107+
108+ static {
109+ GraphicsPrimitiveMgr.registerGeneral(new ScaledBlit(null, null, null));
110+ }
111+
112+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
113+ CompositeType comptype,
114+ SurfaceType dsttype)
115+ {
116+ /*
117+ System.out.println("Constructing general blit for:");
118+ System.out.println("src: "+srctype);
119+ System.out.println("comp: "+comptype);
120+ System.out.println("dst: "+dsttype);
121+ */
122+ return null;
123+ }
124+
125+ public GraphicsPrimitive traceWrap() {
126+ return new TraceScaledBlit(this);
127+ }
128+
129+ private static class TraceScaledBlit extends ScaledBlit {
130+ ScaledBlit target;
131+
132+ public TraceScaledBlit(ScaledBlit target) {
133+ super(target.getSourceType(),
134+ target.getCompositeType(),
135+ target.getDestType());
136+ this.target = target;
137+ }
138+
139+ public GraphicsPrimitive traceWrap() {
140+ return this;
141+ }
142+
143+ public void Scale(SurfaceData src, SurfaceData dst,
144+ Composite comp, Region clip,
145+ int sx1, int sy1,
146+ int sx2, int sy2,
147+ double dx1, double dy1,
148+ double dx2, double dy2)
149+ {
150+ tracePrimitive(target);
151+ target.Scale(src, dst, comp, clip,
152+ sx1, sy1, sx2, sy2,
153+ dx1, dy1, dx2, dy2);
154+ }
155+ }
156+}
java/pkg/sun/java2d/loops/SetDrawLineANY.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/SetDrawPathANY.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/SetDrawPolygonsANY.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/SetDrawRectANY.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/SetFillPathANY.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/SetFillRectANY.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/SetFillSpansANY.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/SolidPixelWriter.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/SurfaceType.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/SurfaceType.java+460−0
@@ -0,0 +1,460 @@
1+/*
2+ * Copyright (c) 1999, 2008, 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+
26+package sun.java2d.loops;
27+
28+import java.awt.image.BufferedImage;
29+import java.awt.image.ColorModel;
30+import sun.awt.image.PixelConverter;
31+import java.util.HashMap;
32+
33+/**
34+ * A SurfaceType object provides a chained description of a type of
35+ * drawing surface. The object will provide a single String constant
36+ * descriptor which is one way of viewing or accessing a particular
37+ * drawing surface as well as a pointer to another SurfaceType which
38+ * describes the same drawing surface in a different (typically more
39+ * generalized) way.
40+ * <p>
41+ * A more specific description of a surface is considered a "subtype"
42+ * and a more general description is considered a "supertype". Thus,
43+ * the deriveSubType method provides a way to create a new SurfaceType
44+ * that is related to but more specific than an existing SurfaceType and
45+ * the getSuperType method provides a way to ask a given SurfaceType
46+ * for a more general way to describe the same surface.
47+ * <p>
48+ * Note that you cannot construct a brand new root for a chain since
49+ * the constructor is private. Every chain of types must at some point
50+ * derive from the Any node provided here using the deriveSubType()
51+ * method. The presence of this common Any node on every chain
52+ * ensures that all chains end with the DESC_ANY descriptor so that
53+ * a suitable General GraphicsPrimitive object can be obtained for
54+ * the indicated surface if all of the more specific searches fail.
55+ */
56+public final class SurfaceType {
57+
58+ private static int unusedUID = 1;
59+ private static HashMap surfaceUIDMap = new HashMap(100);
60+
61+ /*
62+ * CONSTANTS USED BY ALL PRIMITIVES TO DESCRIBE THE SURFACES
63+ * THEY CAN OPERATE ON
64+ */
65+
66+ /**
67+ * surface is unknown color model or sample model.
68+ */
69+ public static final String
70+ DESC_ANY = "Any Surface";
71+
72+ /**
73+ * common surface formats defined in BufferedImage
74+ */
75+ public static final String
76+ DESC_INT_RGB = "Integer RGB";
77+ public static final String
78+ DESC_INT_ARGB = "Integer ARGB";
79+ public static final String
80+ DESC_INT_ARGB_PRE = "Integer ARGB Premultiplied";
81+ public static final String
82+ DESC_INT_BGR = "Integer BGR";
83+ public static final String
84+ DESC_3BYTE_BGR = "3 Byte BGR";
85+ public static final String
86+ DESC_4BYTE_ABGR = "4 Byte ABGR";
87+ public static final String
88+ DESC_4BYTE_ABGR_PRE = "4 Byte ABGR Premultiplied";
89+ public static final String
90+ DESC_USHORT_565_RGB = "Short 565 RGB";
91+ public static final String
92+ DESC_USHORT_555_RGB = "Short 555 RGB";
93+ public static final String
94+ DESC_USHORT_555_RGBx= "Short 555 RGBx";
95+ public static final String
96+ DESC_USHORT_4444_ARGB= "Short 4444 ARGB";
97+ public static final String
98+ DESC_BYTE_GRAY = "8-bit Gray";
99+ public static final String
100+ DESC_USHORT_INDEXED = "16-bit Indexed";
101+ public static final String
102+ DESC_USHORT_GRAY = "16-bit Gray";
103+ public static final String
104+ DESC_BYTE_BINARY = "Packed Binary Bitmap";
105+ public static final String
106+ DESC_BYTE_INDEXED = "8-bit Indexed";
107+
108+ /**
109+ * wildcard format which indicates that the GraphicsPrimitive
110+ * is independent of the color model on an IntegerComponent
111+ * sample model surface
112+ */
113+ public static final String DESC_ANY_INT = "Any Discrete Integer";
114+
115+ /**
116+ * wildcard format which indicates that the GraphicsPrimitive
117+ * is independent of the color model on a ShortComponent
118+ * sample model surface
119+ */
120+ public static final String DESC_ANY_SHORT = "Any Discrete Short";
121+
122+ /**
123+ * wildcard format which indicates that the GraphicsPrimitive
124+ * is independent of the color model on a ByteComponent
125+ * sample model surface
126+ */
127+ public static final String DESC_ANY_BYTE = "Any Discrete Byte";
128+
129+ /**
130+ * wildcard format which indicates that the GraphicsPrimitive
131+ * operates on a surface with 3 component interleaved Raster and
132+ * sample model and a ComponentColorModel with an arbitrary ordering
133+ * of the RGB channels
134+ */
135+ public static final String DESC_ANY_3BYTE = "Any 3 Byte Component";
136+
137+ /**
138+ * wildcard format which indicates that the GraphicsPrimitive
139+ * operates on a surface with 4 component interleaved Raster and
140+ * sample model and a ComponentColorModel with an arbitrary ordering
141+ * of the ARGB channels
142+ */
143+ public static final String DESC_ANY_4BYTE = "Any 4 Byte Component";
144+
145+ /**
146+ * wildcard format which indicates that the GraphicsPrimitive
147+ * operates on a surface with a single component IntegerComponent
148+ * sample model and a DirectColorModel with an arbitrary ordering
149+ * of the RGB channels
150+ */
151+ public static final String DESC_ANY_INT_DCM = "Any Integer DCM";
152+
153+ /**
154+ * additional IntegerComponent types common on Windows
155+ */
156+ public static final String DESC_INT_RGBx = "Integer RGBx";
157+ public static final String DESC_INT_BGRx = "Integer BGRx";
158+
159+ /**
160+ * additional 3 byte format common on Windows
161+ */
162+ public static final String DESC_3BYTE_RGB = "3 Byte RGB";
163+
164+ /**
165+ * common formats for BITMASK transparency.
166+ */
167+ public static final String DESC_INT_ARGB_BM = "Int ARGB (Bitmask)";
168+ public static final String DESC_BYTE_INDEXED_BM = "8-bit Indexed (Bitmask)";
169+
170+ /**
171+ * Opaque 8-bit indexed images
172+ */
173+ public static final String
174+ DESC_BYTE_INDEXED_OPAQUE = "8-bit Indexed (Opaque)";
175+
176+ /**
177+ * Special Gray Scale types for rendering loops. Really indexed
178+ * types, but colormap has all gray values.
179+ */
180+ public static final String DESC_INDEX8_GRAY = "8-bit Palettized Gray";
181+ public static final String DESC_INDEX12_GRAY = "12-bit Palettized Gray";
182+
183+ public static final String
184+ DESC_BYTE_BINARY_1BIT = "Packed Binary 1-bit Bitmap";
185+ public static final String
186+ DESC_BYTE_BINARY_2BIT = "Packed Binary 2-bit Bitmap";
187+ public static final String
188+ DESC_BYTE_BINARY_4BIT = "Packed Binary 4-bit Bitmap";
189+
190+ /**
191+ * Special type for describing the sources of loops that render the
192+ * current foreground color or paint instead of copying colors from
193+ * a source surface.
194+ */
195+ public static final String DESC_ANY_PAINT = "Paint Object";
196+ public static final String DESC_ANY_COLOR = "Single Color";
197+ public static final String DESC_OPAQUE_COLOR = "Opaque Color";
198+ public static final String
199+ DESC_GRADIENT_PAINT = "Gradient Paint";
200+ public static final String
201+ DESC_OPAQUE_GRADIENT_PAINT = "Opaque Gradient Paint";
202+ public static final String
203+ DESC_TEXTURE_PAINT = "Texture Paint";
204+ public static final String
205+ DESC_OPAQUE_TEXTURE_PAINT = "Opaque Texture Paint";
206+ public static final String
207+ DESC_LINEAR_GRADIENT_PAINT = "Linear Gradient Paint";
208+ public static final String
209+ DESC_OPAQUE_LINEAR_GRADIENT_PAINT = "Opaque Linear Gradient Paint";
210+ public static final String
211+ DESC_RADIAL_GRADIENT_PAINT = "Radial Gradient Paint";
212+ public static final String
213+ DESC_OPAQUE_RADIAL_GRADIENT_PAINT = "Opaque Radial Gradient Paint";
214+
215+ /*
216+ * END OF SURFACE TYPE CONSTANTS
217+ */
218+
219+
220+ /**
221+ * The root SurfaceType object for all chains of surface descriptions.
222+ * The root uses the default PixelConverter object, which uses a given
223+ * ColorModel object to calculate its pixelFor() values when asked.
224+ * Any SurfaceType objects that are not created with a specific
225+ * PixelConverter object will inherit this behavior from the root.
226+ */
227+ public static final SurfaceType Any =
228+ new SurfaceType(null, DESC_ANY, PixelConverter.instance);
229+
230+ /*
231+ * START OF SurfaceType OBJECTS FOR THE VARIOUS CONSTANTS
232+ */
233+
234+ public static final SurfaceType
235+ AnyInt = Any.deriveSubType(DESC_ANY_INT);
236+ public static final SurfaceType
237+ AnyShort = Any.deriveSubType(DESC_ANY_SHORT);
238+ public static final SurfaceType
239+ AnyByte = Any.deriveSubType(DESC_ANY_BYTE);
240+ public static final SurfaceType
241+ AnyByteBinary = Any.deriveSubType(DESC_BYTE_BINARY);
242+ public static final SurfaceType
243+ Any3Byte = Any.deriveSubType(DESC_ANY_3BYTE);
244+ public static final SurfaceType
245+ Any4Byte = Any.deriveSubType(DESC_ANY_4BYTE);
246+ public static final SurfaceType
247+ AnyDcm = AnyInt.deriveSubType(DESC_ANY_INT_DCM);
248+
249+ public static final SurfaceType
250+ Custom = Any;
251+ public static final SurfaceType IntRgb =
252+ AnyDcm.deriveSubType(DESC_INT_RGB, PixelConverter.Xrgb.instance);
253+
254+ public static final SurfaceType IntArgb =
255+ AnyDcm.deriveSubType(DESC_INT_ARGB, PixelConverter.Argb.instance);
256+
257+ public static final SurfaceType IntArgbPre =
258+ AnyDcm.deriveSubType(DESC_INT_ARGB_PRE,
259+ PixelConverter.ArgbPre.instance);
260+
261+ public static final SurfaceType IntBgr =
262+ AnyDcm.deriveSubType(DESC_INT_BGR, PixelConverter.Xbgr.instance);
263+
264+ public static final SurfaceType ThreeByteBgr =
265+ Any3Byte.deriveSubType(DESC_3BYTE_BGR, PixelConverter.Xrgb.instance);
266+
267+ public static final SurfaceType FourByteAbgr =
268+ Any4Byte.deriveSubType(DESC_4BYTE_ABGR, PixelConverter.Rgba.instance);
269+
270+ public static final SurfaceType FourByteAbgrPre =
271+ Any4Byte.deriveSubType(DESC_4BYTE_ABGR_PRE,
272+ PixelConverter.RgbaPre.instance);
273+
274+ public static final SurfaceType Ushort565Rgb =
275+ AnyShort.deriveSubType(DESC_USHORT_565_RGB,
276+ PixelConverter.Ushort565Rgb.instance);
277+
278+ public static final SurfaceType Ushort555Rgb =
279+ AnyShort.deriveSubType(DESC_USHORT_555_RGB,
280+ PixelConverter.Ushort555Rgb.instance);
281+
282+ public static final SurfaceType Ushort555Rgbx =
283+ AnyShort.deriveSubType(DESC_USHORT_555_RGBx,
284+ PixelConverter.Ushort555Rgbx.instance);
285+
286+ public static final SurfaceType Ushort4444Argb =
287+ AnyShort.deriveSubType(DESC_USHORT_4444_ARGB,
288+ PixelConverter.Ushort4444Argb.instance);
289+
290+ public static final SurfaceType UshortIndexed =
291+ AnyShort.deriveSubType(DESC_USHORT_INDEXED);
292+
293+ public static final SurfaceType ByteGray =
294+ AnyByte.deriveSubType(DESC_BYTE_GRAY,
295+ PixelConverter.ByteGray.instance);
296+
297+ public static final SurfaceType UshortGray =
298+ AnyShort.deriveSubType(DESC_USHORT_GRAY,
299+ PixelConverter.UshortGray.instance);
300+
301+ public static final SurfaceType ByteBinary1Bit =
302+ AnyByteBinary.deriveSubType(DESC_BYTE_BINARY_1BIT);
303+ public static final SurfaceType ByteBinary2Bit =
304+ AnyByteBinary.deriveSubType(DESC_BYTE_BINARY_2BIT);
305+ public static final SurfaceType ByteBinary4Bit =
306+ AnyByteBinary.deriveSubType(DESC_BYTE_BINARY_4BIT);
307+
308+ public static final SurfaceType ByteIndexed =
309+ AnyByte.deriveSubType(DESC_BYTE_INDEXED);
310+
311+ public static final SurfaceType IntRgbx =
312+ AnyDcm.deriveSubType(DESC_INT_RGBx, PixelConverter.Rgbx.instance);
313+
314+ public static final SurfaceType IntBgrx =
315+ AnyDcm.deriveSubType(DESC_INT_BGRx, PixelConverter.Bgrx.instance);
316+
317+ public static final SurfaceType ThreeByteRgb =
318+ Any3Byte.deriveSubType(DESC_3BYTE_RGB, PixelConverter.Xbgr.instance);
319+
320+ public static final SurfaceType IntArgbBm =
321+ AnyDcm.deriveSubType(DESC_INT_ARGB_BM, PixelConverter.ArgbBm.instance);
322+
323+ public static final SurfaceType ByteIndexedBm =
324+ ByteIndexed.deriveSubType(DESC_BYTE_INDEXED_BM);
325+
326+ public static final SurfaceType ByteIndexedOpaque =
327+ ByteIndexedBm.deriveSubType(DESC_BYTE_INDEXED_OPAQUE);
328+
329+ public static final SurfaceType Index8Gray =
330+ ByteIndexedOpaque.deriveSubType(DESC_INDEX8_GRAY);
331+
332+ public static final SurfaceType Index12Gray =
333+ Any.deriveSubType(DESC_INDEX12_GRAY);
334+
335+ public static final SurfaceType AnyPaint =
336+ Any.deriveSubType(DESC_ANY_PAINT);
337+
338+ public static final SurfaceType AnyColor =
339+ AnyPaint.deriveSubType(DESC_ANY_COLOR);
340+
341+ public static final SurfaceType OpaqueColor =
342+ AnyColor.deriveSubType(DESC_OPAQUE_COLOR);
343+
344+ public static final SurfaceType GradientPaint =
345+ AnyPaint.deriveSubType(DESC_GRADIENT_PAINT);
346+ public static final SurfaceType OpaqueGradientPaint =
347+ GradientPaint.deriveSubType(DESC_OPAQUE_GRADIENT_PAINT);
348+
349+ public static final SurfaceType LinearGradientPaint =
350+ AnyPaint.deriveSubType(DESC_LINEAR_GRADIENT_PAINT);
351+ public static final SurfaceType OpaqueLinearGradientPaint =
352+ LinearGradientPaint.deriveSubType(DESC_OPAQUE_LINEAR_GRADIENT_PAINT);
353+
354+ public static final SurfaceType RadialGradientPaint =
355+ AnyPaint.deriveSubType(DESC_RADIAL_GRADIENT_PAINT);
356+ public static final SurfaceType OpaqueRadialGradientPaint =
357+ RadialGradientPaint.deriveSubType(DESC_OPAQUE_RADIAL_GRADIENT_PAINT);
358+
359+ public static final SurfaceType TexturePaint =
360+ AnyPaint.deriveSubType(DESC_TEXTURE_PAINT);
361+ public static final SurfaceType OpaqueTexturePaint =
362+ TexturePaint.deriveSubType(DESC_OPAQUE_TEXTURE_PAINT);
363+
364+ /*
365+ * END OF SurfaceType OBJECTS FOR THE VARIOUS CONSTANTS
366+ */
367+
368+ /**
369+ * Return a new SurfaceType object which uses this object as its
370+ * more general "supertype" descriptor. If no operation can be
371+ * found that manipulates the type of surface described more exactly
372+ * by desc, then this object will define the more relaxed specification
373+ * of the surface that can be used to find a more general operator.
374+ */
375+ public SurfaceType deriveSubType(String desc) {
376+ return new SurfaceType(this, desc);
377+ }
378+
379+ public SurfaceType deriveSubType(String desc,
380+ PixelConverter pixelConverter) {
381+ return new SurfaceType(this, desc, pixelConverter);
382+ }
383+
384+ private int uniqueID;
385+ private String desc;
386+ private SurfaceType next;
387+ protected PixelConverter pixelConverter;
388+
389+ private SurfaceType(SurfaceType parent, String desc,
390+ PixelConverter pixelConverter) {
391+ next = parent;
392+ this.desc = desc;
393+ this.uniqueID = makeUniqueID(desc);
394+ this.pixelConverter = pixelConverter;
395+ }
396+
397+ private SurfaceType(SurfaceType parent, String desc) {
398+ next = parent;
399+ this.desc = desc;
400+ this.uniqueID = makeUniqueID(desc);
401+ this.pixelConverter = parent.pixelConverter;
402+ }
403+
404+ public synchronized static final int makeUniqueID(String desc) {
405+ Integer i = (Integer) surfaceUIDMap.get((Object) desc);
406+
407+ if (i == null) {
408+ if (unusedUID > 255) {
409+ throw new InternalError("surface type id overflow");
410+ }
411+ i = Integer.valueOf(unusedUID++);
412+ surfaceUIDMap.put(desc, i);
413+ }
414+ return i.intValue();
415+ }
416+
417+ public int getUniqueID() {
418+ return uniqueID;
419+ }
420+
421+ public String getDescriptor() {
422+ return desc;
423+ }
424+
425+ public SurfaceType getSuperType() {
426+ return next;
427+ }
428+
429+ public PixelConverter getPixelConverter() {
430+ return pixelConverter;
431+ }
432+
433+ public int pixelFor(int rgb, ColorModel cm) {
434+ return pixelConverter.rgbToPixel(rgb, cm);
435+ }
436+
437+ public int rgbFor(int pixel, ColorModel cm) {
438+ return pixelConverter.pixelToRgb(pixel, cm);
439+ }
440+
441+ public int getAlphaMask() {
442+ return pixelConverter.getAlphaMask();
443+ }
444+
445+ public int hashCode() {
446+ return desc.hashCode();
447+ }
448+
449+ public boolean equals(Object o) {
450+ if (o instanceof SurfaceType) {
451+ return (((SurfaceType) o).uniqueID == this.uniqueID);
452+ }
453+ return false;
454+ }
455+
456+ public String toString() {
457+ return desc;
458+ }
459+
460+}
java/pkg/sun/java2d/loops/TransformBlit.java+157−0
@@ -0,0 +1,157 @@
1+/*
2+ * Copyright (c) 2003, 2004, 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+
26+package sun.java2d.loops;
27+
28+import java.awt.Composite;
29+import java.awt.geom.AffineTransform;
30+import java.lang.ref.WeakReference;
31+import sun.java2d.SurfaceData;
32+import sun.java2d.loops.GraphicsPrimitive;
33+import sun.java2d.pipe.Region;
34+
35+/**
36+ * TransformBlit
37+ * 1) applies an AffineTransform to a rectangle of pixels while copying
38+ * from one surface to another
39+ * 2) performs compositing of colors based upon a Composite
40+ * parameter
41+ *
42+ * precise behavior is undefined if the source surface
43+ * and the destination surface are the same surface
44+ * with overlapping regions of pixels
45+ */
46+
47+public class TransformBlit extends GraphicsPrimitive
48+{
49+ public static final String methodSignature =
50+ "TransformBlit(...)".toString();
51+
52+ public static final int primTypeID = makePrimTypeID();
53+
54+ private static RenderCache blitcache = new RenderCache(10);
55+
56+ public static TransformBlit locate(SurfaceType srctype,
57+ CompositeType comptype,
58+ SurfaceType dsttype)
59+ {
60+ return (TransformBlit)
61+ GraphicsPrimitiveMgr.locate(primTypeID,
62+ srctype, comptype, dsttype);
63+ }
64+
65+ public static TransformBlit getFromCache(SurfaceType src,
66+ CompositeType comp,
67+ SurfaceType dst)
68+ {
69+ Object o = blitcache.get(src, comp, dst);
70+ if (o != null) {
71+ return (TransformBlit) o;
72+ }
73+ TransformBlit blit = locate(src, comp, dst);
74+ if (blit == null) {
75+ /*
76+ System.out.println("blit loop not found for:");
77+ System.out.println("src: "+src);
78+ System.out.println("comp: "+comp);
79+ System.out.println("dst: "+dst);
80+ */
81+ } else {
82+ blitcache.put(src, comp, dst, blit);
83+ }
84+ return blit;
85+ }
86+
87+ protected TransformBlit(SurfaceType srctype,
88+ CompositeType comptype,
89+ SurfaceType dsttype)
90+ {
91+ super(methodSignature, primTypeID, srctype, comptype, dsttype);
92+ }
93+
94+ public TransformBlit(long pNativePrim,
95+ SurfaceType srctype,
96+ CompositeType comptype,
97+ SurfaceType dsttype)
98+ {
99+ super(pNativePrim, methodSignature, primTypeID,
100+ srctype, comptype, dsttype);
101+ }
102+
103+ public native void Transform(SurfaceData src, SurfaceData dst,
104+ Composite comp, Region clip,
105+ AffineTransform at, int hint,
106+ int srcx, int srcy, int dstx, int dsty,
107+ int width, int height);
108+
109+ // REMIND: do we have a general loop?
110+ static {
111+ GraphicsPrimitiveMgr.registerGeneral(new TransformBlit(null, null,
112+ null));
113+ }
114+
115+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
116+ CompositeType comptype,
117+ SurfaceType dsttype)
118+ {
119+ /*
120+ System.out.println("Constructing general blit for:");
121+ System.out.println("src: "+srctype);
122+ System.out.println("comp: "+comptype);
123+ System.out.println("dst: "+dsttype);
124+ */
125+ return null;
126+ }
127+
128+ public GraphicsPrimitive traceWrap() {
129+ return new TraceTransformBlit(this);
130+ }
131+
132+ private static class TraceTransformBlit extends TransformBlit {
133+ TransformBlit target;
134+
135+ public TraceTransformBlit(TransformBlit target) {
136+ super(target.getSourceType(),
137+ target.getCompositeType(),
138+ target.getDestType());
139+ this.target = target;
140+ }
141+
142+ public GraphicsPrimitive traceWrap() {
143+ return this;
144+ }
145+
146+ public void Transform(SurfaceData src, SurfaceData dst,
147+ Composite comp, Region clip,
148+ AffineTransform at, int hint,
149+ int srcx, int srcy, int dstx, int dsty,
150+ int width, int height)
151+ {
152+ tracePrimitive(target);
153+ target.Transform(src, dst, comp, clip, at, hint,
154+ srcx, srcy, dstx, dsty, width, height);
155+ }
156+ }
157+}
java/pkg/sun/java2d/loops/TransformHelper$TraceTransformHelper.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/TransformHelper.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/TransformHelper.java+140−0
@@ -0,0 +1,140 @@
1+/*
2+ * Copyright (c) 2004, 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+
26+package sun.java2d.loops;
27+
28+import java.awt.Composite;
29+import java.awt.geom.AffineTransform;
30+import java.lang.ref.WeakReference;
31+import sun.java2d.SurfaceData;
32+import sun.java2d.loops.GraphicsPrimitive;
33+import sun.java2d.pipe.Region;
34+
35+/**
36+ * TransformHelper
37+ * 1) applies an AffineTransform to a rectangle of pixels while copying
38+ * from one surface to another
39+ * 2) performs compositing of colors based upon a Composite
40+ * parameter
41+ *
42+ * precise behavior is undefined if the source surface
43+ * and the destination surface are the same surface
44+ * with overlapping regions of pixels
45+ */
46+public class TransformHelper extends GraphicsPrimitive
47+{
48+ public static final String methodSignature =
49+ "TransformHelper(...)".toString();
50+
51+ public static final int primTypeID = makePrimTypeID();
52+
53+ private static RenderCache helpercache = new RenderCache(10);
54+
55+ public static TransformHelper locate(SurfaceType srctype) {
56+ return (TransformHelper)
57+ GraphicsPrimitiveMgr.locate(primTypeID,
58+ srctype,
59+ CompositeType.SrcNoEa,
60+ SurfaceType.IntArgbPre);
61+ }
62+
63+ public static synchronized TransformHelper getFromCache(SurfaceType src) {
64+ Object o = helpercache.get(src, null, null);
65+ if (o != null) {
66+ return (TransformHelper) o;
67+ }
68+ TransformHelper helper = locate(src);
69+ if (helper == null) {
70+ /*
71+ System.out.println("helper loop not found for:");
72+ System.out.println("src: "+src);
73+ */
74+ } else {
75+ helpercache.put(src, null, null, helper);
76+ }
77+ return helper;
78+ }
79+
80+ protected TransformHelper(SurfaceType srctype) {
81+ super(methodSignature, primTypeID, srctype,
82+ CompositeType.SrcNoEa,
83+ SurfaceType.IntArgbPre);
84+ }
85+
86+ public TransformHelper(long pNativePrim, SurfaceType srctype,
87+ CompositeType comptype,
88+ SurfaceType dsttype)
89+ {
90+ super(pNativePrim, methodSignature, primTypeID,
91+ srctype, comptype, dsttype);
92+ }
93+
94+ public native void Transform(MaskBlit output,
95+ SurfaceData src, SurfaceData dst,
96+ Composite comp, Region clip,
97+ AffineTransform itx, int txtype,
98+ int sx1, int sy1, int sx2, int sy2,
99+ int dx1, int dy1, int dx2, int dy2,
100+ int edges[], int dxoff, int dyoff);
101+
102+ public GraphicsPrimitive makePrimitive(SurfaceType srctype,
103+ CompositeType comptype,
104+ SurfaceType dsttype)
105+ {
106+ return null;
107+ }
108+
109+ public GraphicsPrimitive traceWrap() {
110+ return new TraceTransformHelper(this);
111+ }
112+
113+ private static class TraceTransformHelper extends TransformHelper {
114+ TransformHelper target;
115+
116+ public TraceTransformHelper(TransformHelper target) {
117+ super(target.getSourceType());
118+ this.target = target;
119+ }
120+
121+ public GraphicsPrimitive traceWrap() {
122+ return this;
123+ }
124+
125+ public void Transform(MaskBlit output,
126+ SurfaceData src, SurfaceData dst,
127+ Composite comp, Region clip,
128+ AffineTransform itx, int txtype,
129+ int sx1, int sy1, int sx2, int sy2,
130+ int dx1, int dy1, int dx2, int dy2,
131+ int edges[], int dxoff, int dyoff)
132+ {
133+ tracePrimitive(target);
134+ target.Transform(output, src, dst, comp, clip, itx, txtype,
135+ sx1, sy1, sx2, sy2,
136+ dx1, dy1, dx2, dy2,
137+ edges, dxoff, dyoff);
138+ }
139+ }
140+}
java/pkg/sun/java2d/loops/XORComposite.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/XORComposite.java+72−0
@@ -0,0 +1,72 @@
1+/*
2+ * Copyright (c) 1998, 2002, 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+
26+package sun.java2d.loops;
27+
28+import java.awt.image.ColorModel;
29+import java.awt.Color;
30+import java.awt.Composite;
31+import java.awt.CompositeContext;
32+import java.awt.RenderingHints;
33+import sun.java2d.SurfaceData;
34+import sun.java2d.SunCompositeContext;
35+
36+/**
37+ * Bitwise XOR Composite class.
38+ */
39+
40+public final class XORComposite implements Composite {
41+
42+ Color xorColor;
43+ int xorPixel;
44+ int alphaMask;
45+
46+ public XORComposite(Color xorColor, SurfaceData sd) {
47+ this.xorColor = xorColor;
48+
49+ SurfaceType sType = sd.getSurfaceType();
50+
51+ this.xorPixel = sd.pixelFor(xorColor.getRGB());
52+ this.alphaMask = sType.getAlphaMask();
53+ }
54+
55+ public Color getXorColor() {
56+ return xorColor;
57+ }
58+
59+ public int getXorPixel() {
60+ return xorPixel;
61+ }
62+
63+ public int getAlphaMask() {
64+ return alphaMask;
65+ }
66+
67+ public CompositeContext createContext(ColorModel srcColorModel,
68+ ColorModel dstColorModel,
69+ RenderingHints hints) {
70+ return new SunCompositeContext(this, srcColorModel, dstColorModel);
71+ }
72+}
java/pkg/sun/java2d/loops/XorCopyArgbToAny.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/XorDrawGlyphListAAANY.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/XorDrawGlyphListANY.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/XorDrawLineANY.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/XorDrawPathANY.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/XorDrawPolygonsANY.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/XorDrawRectANY.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/XorFillPathANY.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/XorFillRectANY.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/XorFillSpansANY.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/XorPixelWriter$ByteData.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/XorPixelWriter$DoubleData.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/XorPixelWriter$FloatData.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/XorPixelWriter$IntData.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/XorPixelWriter$ShortData.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/XorPixelWriter.class+0−0

Binary file not shown.

java/pkg/sun/java2d/loops/mkfile+38−0
@@ -0,0 +1,38 @@
1+<../../../../../mkconfig
2+
3+TARG=\
4+ Blit.dis\
5+ BlitBg.dis\
6+ CompositeType.dis\
7+ CustomComponent.dis\
8+ DrawGlyphList.dis\
9+ DrawGlyphListAA.dis\
10+ DrawGlyphListLCD.dis\
11+ DrawLine.dis\
12+ DrawParallelogram.dis\
13+ DrawPath.dis\
14+ DrawPolygons.dis\
15+ DrawRect.dis\
16+ FillParallelogram.dis\
17+ FillPath.dis\
18+ FillRect.dis\
19+ FillSpans.dis\
20+ FontInfo.dis\
21+ GeneralRenderer.dis\
22+ GraphicsPrimitive.dis\
23+ GraphicsPrimitiveMgr.dis\
24+ GraphicsPrimitiveProxy.dis\
25+ MaskBlit.dis\
26+ MaskFill.dis\
27+ ProcessPath.dis\
28+ RenderCache.dis\
29+ RenderLoops.dis\
30+ ScaledBlit.dis\
31+ SurfaceType.dis\
32+ TransformBlit.dis\
33+ TransformHelper.dis\
34+ XORComposite.dis\
35+
36+DISBIN=$ROOT/java/dis/java/java/sun/java2d/loops
37+
38+<$ROOT/mkfiles/mkjava
java/pkg/sun/java2d/mkfile+35−0
@@ -0,0 +1,35 @@
1+<../../../../mkconfig
2+
3+DIRS=\
4+ cmm\
5+ loops\
6+ opengl\
7+ pipe\
8+ pisces\
9+
10+TARG=\
11+ DefaultDisposerRecord.dis\
12+ DestSurfaceProvider.dis\
13+ Disposer.dis\
14+ DisposerRecord.dis\
15+ DisposerTarget.dis\
16+ FontSupport.dis\
17+ HeadlessGraphicsEnvironment.dis\
18+ InvalidPipeException.dis\
19+ NullSurfaceData.dis\
20+ Spans.dis\
21+ StateTrackable.dis\
22+ StateTrackableDelegate.dis\
23+ StateTracker.dis\
24+ SunCompositeContext.dis\
25+ SunGraphics2D.dis\
26+ SunGraphicsEnvironment.dis\
27+ Surface.dis\
28+ SurfaceData.dis\
29+ SurfaceDataProxy.dis\
30+ SurfaceManagerFactory.dis\
31+
32+DISBIN=$ROOT/java/dis/java/java/sun/java2d
33+
34+<$ROOT/mkfiles/mkjava
35+<$ROOT/mkfiles/mksubdirs
java/pkg/sun/java2d/opengl/OGLBlitLoops.java+762−0
@@ -0,0 +1,762 @@
1+/*
2+ * Copyright (c) 2003, 2007, 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+
26+package sun.java2d.opengl;
27+
28+import java.awt.Composite;
29+import java.awt.Transparency;
30+import java.awt.geom.AffineTransform;
31+import java.awt.image.AffineTransformOp;
32+import java.awt.image.BufferedImage;
33+import java.awt.image.BufferedImageOp;
34+import java.lang.ref.WeakReference;
35+import sun.java2d.SurfaceData;
36+import sun.java2d.loops.Blit;
37+import sun.java2d.loops.CompositeType;
38+import sun.java2d.loops.GraphicsPrimitive;
39+import sun.java2d.loops.GraphicsPrimitiveMgr;
40+import sun.java2d.loops.ScaledBlit;
41+import sun.java2d.loops.SurfaceType;
42+import sun.java2d.loops.TransformBlit;
43+import sun.java2d.pipe.Region;
44+import sun.java2d.pipe.RenderBuffer;
45+import sun.java2d.pipe.RenderQueue;
46+import static sun.java2d.pipe.BufferedOpCodes.*;
47+
48+class OGLBlitLoops {
49+
50+ static void register() {
51+ Blit blitIntArgbPreToSurface =
52+ new OGLSwToSurfaceBlit(SurfaceType.IntArgbPre,
53+ OGLSurfaceData.PF_INT_ARGB_PRE);
54+ Blit blitIntArgbPreToTexture =
55+ new OGLSwToTextureBlit(SurfaceType.IntArgbPre,
56+ OGLSurfaceData.PF_INT_ARGB_PRE);
57+
58+ GraphicsPrimitive[] primitives = {
59+ // surface->surface ops
60+ new OGLSurfaceToSurfaceBlit(),
61+ new OGLSurfaceToSurfaceScale(),
62+ new OGLSurfaceToSurfaceTransform(),
63+
64+ // render-to-texture surface->surface ops
65+ new OGLRTTSurfaceToSurfaceBlit(),
66+ new OGLRTTSurfaceToSurfaceScale(),
67+ new OGLRTTSurfaceToSurfaceTransform(),
68+
69+ // surface->sw ops
70+ new OGLSurfaceToSwBlit(SurfaceType.IntArgb,
71+ OGLSurfaceData.PF_INT_ARGB),
72+
73+ // sw->surface ops
74+ blitIntArgbPreToSurface,
75+ new OGLSwToSurfaceBlit(SurfaceType.IntRgb,
76+ OGLSurfaceData.PF_INT_RGB),
77+ new OGLSwToSurfaceBlit(SurfaceType.IntRgbx,
78+ OGLSurfaceData.PF_INT_RGBX),
79+ new OGLSwToSurfaceBlit(SurfaceType.IntBgr,
80+ OGLSurfaceData.PF_INT_BGR),
81+ new OGLSwToSurfaceBlit(SurfaceType.IntBgrx,
82+ OGLSurfaceData.PF_INT_BGRX),
83+ new OGLSwToSurfaceBlit(SurfaceType.ThreeByteBgr,
84+ OGLSurfaceData.PF_3BYTE_BGR),
85+ new OGLSwToSurfaceBlit(SurfaceType.Ushort565Rgb,
86+ OGLSurfaceData.PF_USHORT_565_RGB),
87+ new OGLSwToSurfaceBlit(SurfaceType.Ushort555Rgb,
88+ OGLSurfaceData.PF_USHORT_555_RGB),
89+ new OGLSwToSurfaceBlit(SurfaceType.Ushort555Rgbx,
90+ OGLSurfaceData.PF_USHORT_555_RGBX),
91+ new OGLSwToSurfaceBlit(SurfaceType.ByteGray,
92+ OGLSurfaceData.PF_BYTE_GRAY),
93+ new OGLSwToSurfaceBlit(SurfaceType.UshortGray,
94+ OGLSurfaceData.PF_USHORT_GRAY),
95+ new OGLGeneralBlit(OGLSurfaceData.OpenGLSurface,
96+ CompositeType.AnyAlpha,
97+ blitIntArgbPreToSurface),
98+
99+ new OGLSwToSurfaceScale(SurfaceType.IntRgb,
100+ OGLSurfaceData.PF_INT_RGB),
101+ new OGLSwToSurfaceScale(SurfaceType.IntRgbx,
102+ OGLSurfaceData.PF_INT_RGBX),
103+ new OGLSwToSurfaceScale(SurfaceType.IntBgr,
104+ OGLSurfaceData.PF_INT_BGR),
105+ new OGLSwToSurfaceScale(SurfaceType.IntBgrx,
106+ OGLSurfaceData.PF_INT_BGRX),
107+ new OGLSwToSurfaceScale(SurfaceType.ThreeByteBgr,
108+ OGLSurfaceData.PF_3BYTE_BGR),
109+ new OGLSwToSurfaceScale(SurfaceType.Ushort565Rgb,
110+ OGLSurfaceData.PF_USHORT_565_RGB),
111+ new OGLSwToSurfaceScale(SurfaceType.Ushort555Rgb,
112+ OGLSurfaceData.PF_USHORT_555_RGB),
113+ new OGLSwToSurfaceScale(SurfaceType.Ushort555Rgbx,
114+ OGLSurfaceData.PF_USHORT_555_RGBX),
115+ new OGLSwToSurfaceScale(SurfaceType.ByteGray,
116+ OGLSurfaceData.PF_BYTE_GRAY),
117+ new OGLSwToSurfaceScale(SurfaceType.UshortGray,
118+ OGLSurfaceData.PF_USHORT_GRAY),
119+ new OGLSwToSurfaceScale(SurfaceType.IntArgbPre,
120+ OGLSurfaceData.PF_INT_ARGB_PRE),
121+
122+ new OGLSwToSurfaceTransform(SurfaceType.IntRgb,
123+ OGLSurfaceData.PF_INT_RGB),
124+ new OGLSwToSurfaceTransform(SurfaceType.IntRgbx,
125+ OGLSurfaceData.PF_INT_RGBX),
126+ new OGLSwToSurfaceTransform(SurfaceType.IntBgr,
127+ OGLSurfaceData.PF_INT_BGR),
128+ new OGLSwToSurfaceTransform(SurfaceType.IntBgrx,
129+ OGLSurfaceData.PF_INT_BGRX),
130+ new OGLSwToSurfaceTransform(SurfaceType.ThreeByteBgr,
131+ OGLSurfaceData.PF_3BYTE_BGR),
132+ new OGLSwToSurfaceTransform(SurfaceType.Ushort565Rgb,
133+ OGLSurfaceData.PF_USHORT_565_RGB),
134+ new OGLSwToSurfaceTransform(SurfaceType.Ushort555Rgb,
135+ OGLSurfaceData.PF_USHORT_555_RGB),
136+ new OGLSwToSurfaceTransform(SurfaceType.Ushort555Rgbx,
137+ OGLSurfaceData.PF_USHORT_555_RGBX),
138+ new OGLSwToSurfaceTransform(SurfaceType.ByteGray,
139+ OGLSurfaceData.PF_BYTE_GRAY),
140+ new OGLSwToSurfaceTransform(SurfaceType.UshortGray,
141+ OGLSurfaceData.PF_USHORT_GRAY),
142+ new OGLSwToSurfaceTransform(SurfaceType.IntArgbPre,
143+ OGLSurfaceData.PF_INT_ARGB_PRE),
144+
145+ // texture->surface ops
146+ new OGLTextureToSurfaceBlit(),
147+ new OGLTextureToSurfaceScale(),
148+ new OGLTextureToSurfaceTransform(),
149+
150+ // sw->texture ops
151+ blitIntArgbPreToTexture,
152+ new OGLSwToTextureBlit(SurfaceType.IntRgb,
153+ OGLSurfaceData.PF_INT_RGB),
154+ new OGLSwToTextureBlit(SurfaceType.IntRgbx,
155+ OGLSurfaceData.PF_INT_RGBX),
156+ new OGLSwToTextureBlit(SurfaceType.IntBgr,
157+ OGLSurfaceData.PF_INT_BGR),
158+ new OGLSwToTextureBlit(SurfaceType.IntBgrx,
159+ OGLSurfaceData.PF_INT_BGRX),
160+ new OGLSwToTextureBlit(SurfaceType.ThreeByteBgr,
161+ OGLSurfaceData.PF_3BYTE_BGR),
162+ new OGLSwToTextureBlit(SurfaceType.Ushort565Rgb,
163+ OGLSurfaceData.PF_USHORT_565_RGB),
164+ new OGLSwToTextureBlit(SurfaceType.Ushort555Rgb,
165+ OGLSurfaceData.PF_USHORT_555_RGB),
166+ new OGLSwToTextureBlit(SurfaceType.Ushort555Rgbx,
167+ OGLSurfaceData.PF_USHORT_555_RGBX),
168+ new OGLSwToTextureBlit(SurfaceType.ByteGray,
169+ OGLSurfaceData.PF_BYTE_GRAY),
170+ new OGLSwToTextureBlit(SurfaceType.UshortGray,
171+ OGLSurfaceData.PF_USHORT_GRAY),
172+ new OGLGeneralBlit(OGLSurfaceData.OpenGLTexture,
173+ CompositeType.SrcNoEa,
174+ blitIntArgbPreToTexture),
175+ };
176+ GraphicsPrimitiveMgr.register(primitives);
177+ }
178+
179+ /**
180+ * The following offsets are used to pack the parameters in
181+ * createPackedParams(). (They are also used at the native level when
182+ * unpacking the params.)
183+ */
184+ private static final int OFFSET_SRCTYPE = 16;
185+ private static final int OFFSET_HINT = 8;
186+ private static final int OFFSET_TEXTURE = 3;
187+ private static final int OFFSET_RTT = 2;
188+ private static final int OFFSET_XFORM = 1;
189+ private static final int OFFSET_ISOBLIT = 0;
190+
191+ /**
192+ * Packs the given parameters into a single int value in order to save
193+ * space on the rendering queue.
194+ */
195+ private static int createPackedParams(boolean isoblit, boolean texture,
196+ boolean rtt, boolean xform,
197+ int hint, int srctype)
198+ {
199+ return
200+ ((srctype << OFFSET_SRCTYPE) |
201+ (hint << OFFSET_HINT ) |
202+ ((texture ? 1 : 0) << OFFSET_TEXTURE) |
203+ ((rtt ? 1 : 0) << OFFSET_RTT ) |
204+ ((xform ? 1 : 0) << OFFSET_XFORM ) |
205+ ((isoblit ? 1 : 0) << OFFSET_ISOBLIT));
206+ }
207+
208+ /**
209+ * Enqueues a BLIT operation with the given parameters. Note that the
210+ * RenderQueue lock must be held before calling this method.
211+ */
212+ private static void enqueueBlit(RenderQueue rq,
213+ SurfaceData src, SurfaceData dst,
214+ int packedParams,
215+ int sx1, int sy1,
216+ int sx2, int sy2,
217+ double dx1, double dy1,
218+ double dx2, double dy2)
219+ {
220+ // assert rq.lock.isHeldByCurrentThread();
221+ RenderBuffer buf = rq.getBuffer();
222+ rq.ensureCapacityAndAlignment(72, 24);
223+ buf.putInt(BLIT);
224+ buf.putInt(packedParams);
225+ buf.putInt(sx1).putInt(sy1);
226+ buf.putInt(sx2).putInt(sy2);
227+ buf.putDouble(dx1).putDouble(dy1);
228+ buf.putDouble(dx2).putDouble(dy2);
229+ buf.putLong(src.getNativeOps());
230+ buf.putLong(dst.getNativeOps());
231+ }
232+
233+ static void Blit(SurfaceData srcData, SurfaceData dstData,
234+ Composite comp, Region clip,
235+ AffineTransform xform, int hint,
236+ int sx1, int sy1,
237+ int sx2, int sy2,
238+ double dx1, double dy1,
239+ double dx2, double dy2,
240+ int srctype, boolean texture)
241+ {
242+ int ctxflags = 0;
243+ if (srcData.getTransparency() == Transparency.OPAQUE) {
244+ ctxflags |= OGLContext.SRC_IS_OPAQUE;
245+ }
246+
247+ OGLRenderQueue rq = OGLRenderQueue.getInstance();
248+ rq.lock();
249+ try {
250+ // make sure the RenderQueue keeps a hard reference to the
251+ // source (sysmem) SurfaceData to prevent it from being
252+ // disposed while the operation is processed on the QFT
253+ rq.addReference(srcData);
254+
255+ OGLSurfaceData oglDst = (OGLSurfaceData)dstData;
256+ if (texture) {
257+ // make sure we have a current context before uploading
258+ // the sysmem data to the texture object
259+ OGLGraphicsConfig gc = oglDst.getOGLGraphicsConfig();
260+ OGLContext.setScratchSurface(gc);
261+ } else {
262+ OGLContext.validateContext(oglDst, oglDst,
263+ clip, comp, xform, null, null,
264+ ctxflags);
265+ }
266+
267+ int packedParams = createPackedParams(false, texture,
268+ false, xform != null,
269+ hint, srctype);
270+ enqueueBlit(rq, srcData, dstData,
271+ packedParams,
272+ sx1, sy1, sx2, sy2,
273+ dx1, dy1, dx2, dy2);
274+
275+ // always flush immediately, since we (currently) have no means
276+ // of tracking changes to the system memory surface
277+ rq.flushNow();
278+ } finally {
279+ rq.unlock();
280+ }
281+ }
282+
283+ /**
284+ * Note: The srcImg and biop parameters are only used when invoked
285+ * from the OGLBufImgOps.renderImageWithOp() method; in all other cases,
286+ * this method can be called with null values for those two parameters,
287+ * and they will be effectively ignored.
288+ */
289+ static void IsoBlit(SurfaceData srcData, SurfaceData dstData,
290+ BufferedImage srcImg, BufferedImageOp biop,
291+ Composite comp, Region clip,
292+ AffineTransform xform, int hint,
293+ int sx1, int sy1,
294+ int sx2, int sy2,
295+ double dx1, double dy1,
296+ double dx2, double dy2,
297+ boolean texture)
298+ {
299+ int ctxflags = 0;
300+ if (srcData.getTransparency() == Transparency.OPAQUE) {
301+ ctxflags |= OGLContext.SRC_IS_OPAQUE;
302+ }
303+
304+ OGLRenderQueue rq = OGLRenderQueue.getInstance();
305+ rq.lock();
306+ try {
307+ OGLSurfaceData oglSrc = (OGLSurfaceData)srcData;
308+ OGLSurfaceData oglDst = (OGLSurfaceData)dstData;
309+ int srctype = oglSrc.getType();
310+ boolean rtt;
311+ OGLSurfaceData srcCtxData;
312+ if (srctype == OGLSurfaceData.TEXTURE) {
313+ // the source is a regular texture object; we substitute
314+ // the destination surface for the purposes of making a
315+ // context current
316+ rtt = false;
317+ srcCtxData = oglDst;
318+ } else {
319+ // the source is a pbuffer, backbuffer, or render-to-texture
320+ // surface; we set rtt to true to differentiate this kind
321+ // of surface from a regular texture object
322+ rtt = true;
323+ if (srctype == OGLSurfaceData.FBOBJECT) {
324+ srcCtxData = oglDst;
325+ } else {
326+ srcCtxData = oglSrc;
327+ }
328+ }
329+
330+ OGLContext.validateContext(srcCtxData, oglDst,
331+ clip, comp, xform, null, null,
332+ ctxflags);
333+
334+ if (biop != null) {
335+ OGLBufImgOps.enableBufImgOp(rq, oglSrc, srcImg, biop);
336+ }
337+
338+ int packedParams = createPackedParams(true, texture,
339+ rtt, xform != null,
340+ hint, 0 /*unused*/);
341+ enqueueBlit(rq, srcData, dstData,
342+ packedParams,
343+ sx1, sy1, sx2, sy2,
344+ dx1, dy1, dx2, dy2);
345+
346+ if (biop != null) {
347+ OGLBufImgOps.disableBufImgOp(rq, biop);
348+ }
349+
350+ if (rtt && (oglDst.getType() == OGLSurfaceData.WINDOW)) {
351+ // we only have to flush immediately when copying from a
352+ // (non-texture) surface to the screen; otherwise Swing apps
353+ // might appear unresponsive until the auto-flush completes
354+ rq.flushNow();
355+ }
356+ } finally {
357+ rq.unlock();
358+ }
359+ }
360+}
361+
362+class OGLSurfaceToSurfaceBlit extends Blit {
363+
364+ OGLSurfaceToSurfaceBlit() {
365+ super(OGLSurfaceData.OpenGLSurface,
366+ CompositeType.AnyAlpha,
367+ OGLSurfaceData.OpenGLSurface);
368+ }
369+
370+ public void Blit(SurfaceData src, SurfaceData dst,
371+ Composite comp, Region clip,
372+ int sx, int sy, int dx, int dy, int w, int h)
373+ {
374+ OGLBlitLoops.IsoBlit(src, dst,
375+ null, null,
376+ comp, clip, null,
377+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
378+ sx, sy, sx+w, sy+h,
379+ dx, dy, dx+w, dy+h,
380+ false);
381+ }
382+}
383+
384+class OGLSurfaceToSurfaceScale extends ScaledBlit {
385+
386+ OGLSurfaceToSurfaceScale() {
387+ super(OGLSurfaceData.OpenGLSurface,
388+ CompositeType.AnyAlpha,
389+ OGLSurfaceData.OpenGLSurface);
390+ }
391+
392+ public void Scale(SurfaceData src, SurfaceData dst,
393+ Composite comp, Region clip,
394+ int sx1, int sy1,
395+ int sx2, int sy2,
396+ double dx1, double dy1,
397+ double dx2, double dy2)
398+ {
399+ OGLBlitLoops.IsoBlit(src, dst,
400+ null, null,
401+ comp, clip, null,
402+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
403+ sx1, sy1, sx2, sy2,
404+ dx1, dy1, dx2, dy2,
405+ false);
406+ }
407+}
408+
409+class OGLSurfaceToSurfaceTransform extends TransformBlit {
410+
411+ OGLSurfaceToSurfaceTransform() {
412+ super(OGLSurfaceData.OpenGLSurface,
413+ CompositeType.AnyAlpha,
414+ OGLSurfaceData.OpenGLSurface);
415+ }
416+
417+ public void Transform(SurfaceData src, SurfaceData dst,
418+ Composite comp, Region clip,
419+ AffineTransform at, int hint,
420+ int sx, int sy, int dx, int dy,
421+ int w, int h)
422+ {
423+ OGLBlitLoops.IsoBlit(src, dst,
424+ null, null,
425+ comp, clip, at, hint,
426+ sx, sy, sx+w, sy+h,
427+ dx, dy, dx+w, dy+h,
428+ false);
429+ }
430+}
431+
432+class OGLRTTSurfaceToSurfaceBlit extends Blit {
433+
434+ OGLRTTSurfaceToSurfaceBlit() {
435+ super(OGLSurfaceData.OpenGLSurfaceRTT,
436+ CompositeType.AnyAlpha,
437+ OGLSurfaceData.OpenGLSurface);
438+ }
439+
440+ public void Blit(SurfaceData src, SurfaceData dst,
441+ Composite comp, Region clip,
442+ int sx, int sy, int dx, int dy, int w, int h)
443+ {
444+ OGLBlitLoops.IsoBlit(src, dst,
445+ null, null,
446+ comp, clip, null,
447+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
448+ sx, sy, sx+w, sy+h,
449+ dx, dy, dx+w, dy+h,
450+ true);
451+ }
452+}
453+
454+class OGLRTTSurfaceToSurfaceScale extends ScaledBlit {
455+
456+ OGLRTTSurfaceToSurfaceScale() {
457+ super(OGLSurfaceData.OpenGLSurfaceRTT,
458+ CompositeType.AnyAlpha,
459+ OGLSurfaceData.OpenGLSurface);
460+ }
461+
462+ public void Scale(SurfaceData src, SurfaceData dst,
463+ Composite comp, Region clip,
464+ int sx1, int sy1,
465+ int sx2, int sy2,
466+ double dx1, double dy1,
467+ double dx2, double dy2)
468+ {
469+ OGLBlitLoops.IsoBlit(src, dst,
470+ null, null,
471+ comp, clip, null,
472+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
473+ sx1, sy1, sx2, sy2,
474+ dx1, dy1, dx2, dy2,
475+ true);
476+ }
477+}
478+
479+class OGLRTTSurfaceToSurfaceTransform extends TransformBlit {
480+
481+ OGLRTTSurfaceToSurfaceTransform() {
482+ super(OGLSurfaceData.OpenGLSurfaceRTT,
483+ CompositeType.AnyAlpha,
484+ OGLSurfaceData.OpenGLSurface);
485+ }
486+
487+ public void Transform(SurfaceData src, SurfaceData dst,
488+ Composite comp, Region clip,
489+ AffineTransform at, int hint,
490+ int sx, int sy, int dx, int dy, int w, int h)
491+ {
492+ OGLBlitLoops.IsoBlit(src, dst,
493+ null, null,
494+ comp, clip, at, hint,
495+ sx, sy, sx+w, sy+h,
496+ dx, dy, dx+w, dy+h,
497+ true);
498+ }
499+}
500+
501+class OGLSurfaceToSwBlit extends Blit {
502+
503+ private int typeval;
504+
505+ // REMIND: destination will actually be opaque/premultiplied...
506+ OGLSurfaceToSwBlit(SurfaceType dstType, int typeval) {
507+ super(OGLSurfaceData.OpenGLSurface,
508+ CompositeType.SrcNoEa,
509+ dstType);
510+ this.typeval = typeval;
511+ }
512+
513+ public void Blit(SurfaceData src, SurfaceData dst,
514+ Composite comp, Region clip,
515+ int sx, int sy, int dx, int dy,
516+ int w, int h)
517+ {
518+ OGLRenderQueue rq = OGLRenderQueue.getInstance();
519+ rq.lock();
520+ try {
521+ // make sure the RenderQueue keeps a hard reference to the
522+ // destination (sysmem) SurfaceData to prevent it from being
523+ // disposed while the operation is processed on the QFT
524+ rq.addReference(dst);
525+
526+ RenderBuffer buf = rq.getBuffer();
527+ OGLContext.validateContext((OGLSurfaceData)src);
528+
529+ rq.ensureCapacityAndAlignment(48, 32);
530+ buf.putInt(SURFACE_TO_SW_BLIT);
531+ buf.putInt(sx).putInt(sy);
532+ buf.putInt(dx).putInt(dy);
533+ buf.putInt(w).putInt(h);
534+ buf.putInt(typeval);
535+ buf.putLong(src.getNativeOps());
536+ buf.putLong(dst.getNativeOps());
537+
538+ // always flush immediately
539+ rq.flushNow();
540+ } finally {
541+ rq.unlock();
542+ }
543+ }
544+}
545+
546+class OGLSwToSurfaceBlit extends Blit {
547+
548+ private int typeval;
549+
550+ OGLSwToSurfaceBlit(SurfaceType srcType, int typeval) {
551+ super(srcType,
552+ CompositeType.AnyAlpha,
553+ OGLSurfaceData.OpenGLSurface);
554+ this.typeval = typeval;
555+ }
556+
557+ public void Blit(SurfaceData src, SurfaceData dst,
558+ Composite comp, Region clip,
559+ int sx, int sy, int dx, int dy, int w, int h)
560+ {
561+ OGLBlitLoops.Blit(src, dst,
562+ comp, clip, null,
563+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
564+ sx, sy, sx+w, sy+h,
565+ dx, dy, dx+w, dy+h,
566+ typeval, false);
567+ }
568+}
569+
570+class OGLSwToSurfaceScale extends ScaledBlit {
571+
572+ private int typeval;
573+
574+ OGLSwToSurfaceScale(SurfaceType srcType, int typeval) {
575+ super(srcType,
576+ CompositeType.AnyAlpha,
577+ OGLSurfaceData.OpenGLSurface);
578+ this.typeval = typeval;
579+ }
580+
581+ public void Scale(SurfaceData src, SurfaceData dst,
582+ Composite comp, Region clip,
583+ int sx1, int sy1,
584+ int sx2, int sy2,
585+ double dx1, double dy1,
586+ double dx2, double dy2)
587+ {
588+ OGLBlitLoops.Blit(src, dst,
589+ comp, clip, null,
590+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
591+ sx1, sy1, sx2, sy2,
592+ dx1, dy1, dx2, dy2,
593+ typeval, false);
594+ }
595+}
596+
597+class OGLSwToSurfaceTransform extends TransformBlit {
598+
599+ private int typeval;
600+
601+ OGLSwToSurfaceTransform(SurfaceType srcType, int typeval) {
602+ super(srcType,
603+ CompositeType.AnyAlpha,
604+ OGLSurfaceData.OpenGLSurface);
605+ this.typeval = typeval;
606+ }
607+
608+ public void Transform(SurfaceData src, SurfaceData dst,
609+ Composite comp, Region clip,
610+ AffineTransform at, int hint,
611+ int sx, int sy, int dx, int dy, int w, int h)
612+ {
613+ OGLBlitLoops.Blit(src, dst,
614+ comp, clip, at, hint,
615+ sx, sy, sx+w, sy+h,
616+ dx, dy, dx+w, dy+h,
617+ typeval, false);
618+ }
619+}
620+
621+class OGLSwToTextureBlit extends Blit {
622+
623+ private int typeval;
624+
625+ OGLSwToTextureBlit(SurfaceType srcType, int typeval) {
626+ super(srcType,
627+ CompositeType.SrcNoEa,
628+ OGLSurfaceData.OpenGLTexture);
629+ this.typeval = typeval;
630+ }
631+
632+ public void Blit(SurfaceData src, SurfaceData dst,
633+ Composite comp, Region clip,
634+ int sx, int sy, int dx, int dy, int w, int h)
635+ {
636+ OGLBlitLoops.Blit(src, dst,
637+ comp, clip, null,
638+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
639+ sx, sy, sx+w, sy+h,
640+ dx, dy, dx+w, dy+h,
641+ typeval, true);
642+ }
643+}
644+
645+class OGLTextureToSurfaceBlit extends Blit {
646+
647+ OGLTextureToSurfaceBlit() {
648+ super(OGLSurfaceData.OpenGLTexture,
649+ CompositeType.AnyAlpha,
650+ OGLSurfaceData.OpenGLSurface);
651+ }
652+
653+ public void Blit(SurfaceData src, SurfaceData dst,
654+ Composite comp, Region clip,
655+ int sx, int sy, int dx, int dy, int w, int h)
656+ {
657+ OGLBlitLoops.IsoBlit(src, dst,
658+ null, null,
659+ comp, clip, null,
660+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
661+ sx, sy, sx+w, sy+h,
662+ dx, dy, dx+w, dy+h,
663+ true);
664+ }
665+}
666+
667+class OGLTextureToSurfaceScale extends ScaledBlit {
668+
669+ OGLTextureToSurfaceScale() {
670+ super(OGLSurfaceData.OpenGLTexture,
671+ CompositeType.AnyAlpha,
672+ OGLSurfaceData.OpenGLSurface);
673+ }
674+
675+ public void Scale(SurfaceData src, SurfaceData dst,
676+ Composite comp, Region clip,
677+ int sx1, int sy1,
678+ int sx2, int sy2,
679+ double dx1, double dy1,
680+ double dx2, double dy2)
681+ {
682+ OGLBlitLoops.IsoBlit(src, dst,
683+ null, null,
684+ comp, clip, null,
685+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
686+ sx1, sy1, sx2, sy2,
687+ dx1, dy1, dx2, dy2,
688+ true);
689+ }
690+}
691+
692+class OGLTextureToSurfaceTransform extends TransformBlit {
693+
694+ OGLTextureToSurfaceTransform() {
695+ super(OGLSurfaceData.OpenGLTexture,
696+ CompositeType.AnyAlpha,
697+ OGLSurfaceData.OpenGLSurface);
698+ }
699+
700+ public void Transform(SurfaceData src, SurfaceData dst,
701+ Composite comp, Region clip,
702+ AffineTransform at, int hint,
703+ int sx, int sy, int dx, int dy,
704+ int w, int h)
705+ {
706+ OGLBlitLoops.IsoBlit(src, dst,
707+ null, null,
708+ comp, clip, at, hint,
709+ sx, sy, sx+w, sy+h,
710+ dx, dy, dx+w, dy+h,
711+ true);
712+ }
713+}
714+
715+/**
716+ * This general Blit implemenation converts any source surface to an
717+ * intermediate IntArgbPre surface, and then uses the more specific
718+ * IntArgbPre->OpenGLSurface/Texture loop to get the intermediate
719+ * (premultiplied) surface down to OpenGL.
720+ */
721+class OGLGeneralBlit extends Blit {
722+
723+ private Blit performop;
724+ private WeakReference srcTmp;
725+
726+ OGLGeneralBlit(SurfaceType dstType,
727+ CompositeType compType,
728+ Blit performop)
729+ {
730+ super(SurfaceType.Any, compType, dstType);
731+ this.performop = performop;
732+ }
733+
734+ public synchronized void Blit(SurfaceData src, SurfaceData dst,
735+ Composite comp, Region clip,
736+ int sx, int sy, int dx, int dy,
737+ int w, int h)
738+ {
739+ Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),
740+ CompositeType.SrcNoEa,
741+ SurfaceType.IntArgbPre);
742+
743+ SurfaceData cachedSrc = null;
744+ if (srcTmp != null) {
745+ // use cached intermediate surface, if available
746+ cachedSrc = (SurfaceData)srcTmp.get();
747+ }
748+
749+ // convert source to IntArgbPre
750+ src = convertFrom(convertsrc, src, sx, sy, w, h,
751+ cachedSrc, BufferedImage.TYPE_INT_ARGB_PRE);
752+
753+ // copy IntArgbPre intermediate surface to OpenGL surface
754+ performop.Blit(src, dst, comp, clip,
755+ 0, 0, dx, dy, w, h);
756+
757+ if (src != cachedSrc) {
758+ // cache the intermediate surface
759+ srcTmp = new WeakReference(src);
760+ }
761+ }
762+}
java/pkg/sun/java2d/opengl/OGLBufImgOps.java+115−0
@@ -0,0 +1,115 @@
1+/*
2+ * Copyright (c) 2007, 2008, 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+
26+package sun.java2d.opengl;
27+
28+import java.awt.image.AffineTransformOp;
29+import java.awt.image.BufferedImage;
30+import java.awt.image.BufferedImageOp;
31+import java.awt.image.ConvolveOp;
32+import java.awt.image.LookupOp;
33+import java.awt.image.RescaleOp;
34+import sun.java2d.SunGraphics2D;
35+import sun.java2d.SurfaceData;
36+import sun.java2d.loops.CompositeType;
37+import sun.java2d.pipe.BufferedBufImgOps;
38+import static sun.java2d.opengl.OGLContext.OGLContextCaps.*;
39+
40+class OGLBufImgOps extends BufferedBufImgOps {
41+
42+ /**
43+ * This method is called from OGLDrawImage.transformImage() only. It
44+ * validates the provided BufferedImageOp to determine whether the op
45+ * is one that can be accelerated by the OGL pipeline. If the operation
46+ * cannot be completed for any reason, this method returns false;
47+ * otherwise, the given BufferedImage is rendered to the destination
48+ * using the provided BufferedImageOp and this method returns true.
49+ */
50+ static boolean renderImageWithOp(SunGraphics2D sg, BufferedImage img,
51+ BufferedImageOp biop, int x, int y)
52+ {
53+ // Validate the provided BufferedImage (make sure it is one that
54+ // is supported, and that its properties are acceleratable)
55+ if (biop instanceof ConvolveOp) {
56+ if (!isConvolveOpValid((ConvolveOp)biop)) {
57+ return false;
58+ }
59+ } else if (biop instanceof RescaleOp) {
60+ if (!isRescaleOpValid((RescaleOp)biop, img)) {
61+ return false;
62+ }
63+ } else if (biop instanceof LookupOp) {
64+ if (!isLookupOpValid((LookupOp)biop, img)) {
65+ return false;
66+ }
67+ } else {
68+ // No acceleration for other BufferedImageOps (yet)
69+ return false;
70+ }
71+
72+ SurfaceData dstData = sg.surfaceData;
73+ if (!(dstData instanceof OGLSurfaceData) ||
74+ (sg.interpolationType == AffineTransformOp.TYPE_BICUBIC) ||
75+ (sg.compositeState > SunGraphics2D.COMP_ALPHA))
76+ {
77+ return false;
78+ }
79+
80+ SurfaceData srcData =
81+ dstData.getSourceSurfaceData(img, sg.TRANSFORM_ISIDENT,
82+ CompositeType.SrcOver, null);
83+ if (!(srcData instanceof OGLSurfaceData)) {
84+ // REMIND: this hack tries to ensure that we have a cached texture
85+ srcData =
86+ dstData.getSourceSurfaceData(img, sg.TRANSFORM_ISIDENT,
87+ CompositeType.SrcOver, null);
88+ if (!(srcData instanceof OGLSurfaceData)) {
89+ return false;
90+ }
91+ }
92+
93+ // Verify that the source surface is actually a texture and
94+ // that the operation is supported
95+ OGLSurfaceData oglSrc = (OGLSurfaceData)srcData;
96+ OGLGraphicsConfig gc = oglSrc.getOGLGraphicsConfig();
97+ if (oglSrc.getType() != OGLSurfaceData.TEXTURE ||
98+ !gc.isCapPresent(CAPS_EXT_BIOP_SHADER))
99+ {
100+ return false;
101+ }
102+
103+ int sw = img.getWidth();
104+ int sh = img.getHeight();
105+ OGLBlitLoops.IsoBlit(srcData, dstData,
106+ img, biop,
107+ sg.composite, sg.getCompClip(),
108+ sg.transform, sg.interpolationType,
109+ 0, 0, sw, sh,
110+ x, y, x+sw, y+sh,
111+ true);
112+
113+ return true;
114+ }
115+}
java/pkg/sun/java2d/opengl/OGLContext.java+220−0
@@ -0,0 +1,220 @@
1+/*
2+ * Copyright (c) 2004, 2008, 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+
26+package sun.java2d.opengl;
27+
28+import sun.java2d.pipe.BufferedContext;
29+import sun.java2d.pipe.RenderBuffer;
30+import sun.java2d.pipe.RenderQueue;
31+import sun.java2d.pipe.hw.ContextCapabilities;
32+import static sun.java2d.pipe.BufferedOpCodes.*;
33+import static sun.java2d.pipe.hw.ContextCapabilities.*;
34+
35+/**
36+ * Note that the RenderQueue lock must be acquired before calling any of
37+ * the methods in this class.
38+ */
39+public class OGLContext extends BufferedContext {
40+
41+ private final OGLGraphicsConfig config;
42+
43+ OGLContext(RenderQueue rq, OGLGraphicsConfig config) {
44+ super(rq);
45+ this.config = config;
46+ }
47+
48+ /**
49+ * Convenience method that delegates to setScratchSurface() below.
50+ */
51+ static void setScratchSurface(OGLGraphicsConfig gc) {
52+ setScratchSurface(gc.getNativeConfigInfo());
53+ }
54+
55+ /**
56+ * Makes the given GraphicsConfig's context current to its associated
57+ * "scratch surface". Each GraphicsConfig maintains a native context
58+ * (GLXContext on Unix, HGLRC on Windows) as well as a native pbuffer
59+ * known as the "scratch surface". By making the context current to the
60+ * scratch surface, we are assured that we have a current context for
61+ * the relevant GraphicsConfig, and can therefore perform operations
62+ * depending on the capabilities of that GraphicsConfig. For example,
63+ * if the GraphicsConfig supports the GL_ARB_texture_non_power_of_two
64+ * extension, then we should be able to make a non-pow2 texture for this
65+ * GraphicsConfig once we make the context current to the scratch surface.
66+ *
67+ * This method should be used for operations with an OpenGL texture
68+ * as the destination surface (e.g. a sw->texture blit loop), or in those
69+ * situations where we may not otherwise have a current context (e.g.
70+ * when disposing a texture-based surface).
71+ */
72+ static void setScratchSurface(long pConfigInfo) {
73+ // assert OGLRenderQueue.getInstance().lock.isHeldByCurrentThread();
74+
75+ // invalidate the current context
76+ currentContext = null;
77+
78+ // set the scratch context
79+ OGLRenderQueue rq = OGLRenderQueue.getInstance();
80+ RenderBuffer buf = rq.getBuffer();
81+ rq.ensureCapacityAndAlignment(12, 4);
82+ buf.putInt(SET_SCRATCH_SURFACE);
83+ buf.putLong(pConfigInfo);
84+ }
85+
86+ /**
87+ * Invalidates the currentContext field to ensure that we properly
88+ * revalidate the OGLContext (make it current, etc.) next time through
89+ * the validate() method. This is typically invoked from methods
90+ * that affect the current context state (e.g. disposing a context or
91+ * surface).
92+ */
93+ static void invalidateCurrentContext() {
94+ // assert OGLRenderQueue.getInstance().lock.isHeldByCurrentThread();
95+
96+ // invalidate the current Java-level context so that we
97+ // revalidate everything the next time around
98+ if (currentContext != null) {
99+ currentContext.invalidateContext();
100+ currentContext = null;
101+ }
102+
103+ // invalidate the context reference at the native level, and
104+ // then flush the queue so that we have no pending operations
105+ // dependent on the current context
106+ OGLRenderQueue rq = OGLRenderQueue.getInstance();
107+ rq.ensureCapacity(4);
108+ rq.getBuffer().putInt(INVALIDATE_CONTEXT);
109+ rq.flushNow();
110+ }
111+
112+ public RenderQueue getRenderQueue() {
113+ return OGLRenderQueue.getInstance();
114+ }
115+
116+ /**
117+ * Returns a string representing adapter id (vendor, renderer, version).
118+ * Must be called on the rendering thread.
119+ *
120+ * @return an id string for the adapter
121+ */
122+ static final native String getOGLIdString();
123+
124+ @Override
125+ public void saveState() {
126+ // assert rq.lock.isHeldByCurrentThread();
127+
128+ // reset all attributes of this and current contexts
129+ invalidateContext();
130+ invalidateCurrentContext();
131+
132+ setScratchSurface(config);
133+
134+ // save the state on the native level
135+ rq.ensureCapacity(4);
136+ buf.putInt(SAVE_STATE);
137+ rq.flushNow();
138+ }
139+
140+ @Override
141+ public void restoreState() {
142+ // assert rq.lock.isHeldByCurrentThread();
143+
144+ // reset all attributes of this and current contexts
145+ invalidateContext();
146+ invalidateCurrentContext();
147+
148+ setScratchSurface(config);
149+
150+ // restore the state on the native level
151+ rq.ensureCapacity(4);
152+ buf.putInt(RESTORE_STATE);
153+ rq.flushNow();
154+ }
155+
156+ static class OGLContextCaps extends ContextCapabilities {
157+ /**
158+ * Indicates the presence of the GL_EXT_framebuffer_object extension.
159+ * This cap will only be set if the fbobject system property has been
160+ * enabled and we are able to create an FBO with depth buffer.
161+ */
162+ static final int CAPS_EXT_FBOBJECT =
163+ (CAPS_RT_TEXTURE_ALPHA | CAPS_RT_TEXTURE_OPAQUE);
164+ /** Indicates that the context supports a stored alpha channel. */
165+ static final int CAPS_STORED_ALPHA = CAPS_RT_PLAIN_ALPHA;
166+ /** Indicates that the context is doublebuffered. */
167+ static final int CAPS_DOUBLEBUFFERED = (FIRST_PRIVATE_CAP << 0);
168+ /**
169+ * Indicates the presence of the GL_ARB_fragment_shader extension.
170+ * This cap will only be set if the lcdshader system property has been
171+ * enabled and the hardware supports the minimum number of texture units
172+ */
173+ static final int CAPS_EXT_LCD_SHADER = (FIRST_PRIVATE_CAP << 1);
174+ /**
175+ * Indicates the presence of the GL_ARB_fragment_shader extension.
176+ * This cap will only be set if the biopshader system property has been
177+ * enabled and the hardware meets our minimum requirements.
178+ */
179+ static final int CAPS_EXT_BIOP_SHADER = (FIRST_PRIVATE_CAP << 2);
180+ /**
181+ * Indicates the presence of the GL_ARB_fragment_shader extension.
182+ * This cap will only be set if the gradshader system property has been
183+ * enabled and the hardware meets our minimum requirements.
184+ */
185+ static final int CAPS_EXT_GRAD_SHADER = (FIRST_PRIVATE_CAP << 3);
186+ /** Indicates the presence of the GL_ARB_texture_rectangle extension. */
187+ static final int CAPS_EXT_TEXRECT = (FIRST_PRIVATE_CAP << 4);
188+
189+ OGLContextCaps(int caps, String adapterId) {
190+ super(caps, adapterId);
191+ }
192+
193+ @Override
194+ public String toString() {
195+ StringBuffer buf = new StringBuffer(super.toString());
196+ if ((caps & CAPS_EXT_FBOBJECT) != 0) {
197+ buf.append("CAPS_EXT_FBOBJECT|");
198+ }
199+ if ((caps & CAPS_STORED_ALPHA) != 0) {
200+ buf.append("CAPS_STORED_ALPHA|");
201+ }
202+ if ((caps & CAPS_DOUBLEBUFFERED) != 0) {
203+ buf.append("CAPS_DOUBLEBUFFERED|");
204+ }
205+ if ((caps & CAPS_EXT_LCD_SHADER) != 0) {
206+ buf.append("CAPS_EXT_LCD_SHADER|");
207+ }
208+ if ((caps & CAPS_EXT_BIOP_SHADER) != 0) {
209+ buf.append("CAPS_BIOP_SHADER|");
210+ }
211+ if ((caps & CAPS_EXT_GRAD_SHADER) != 0) {
212+ buf.append("CAPS_EXT_GRAD_SHADER|");
213+ }
214+ if ((caps & CAPS_EXT_TEXRECT) != 0) {
215+ buf.append("CAPS_EXT_TEXRECT|");
216+ }
217+ return buf.toString();
218+ }
219+ }
220+}
java/pkg/sun/java2d/opengl/OGLDrawImage.java+113−0
@@ -0,0 +1,113 @@
1+/*
2+ * Copyright (c) 2003, 2007, 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+
26+package sun.java2d.opengl;
27+
28+import java.awt.Color;
29+import java.awt.Image;
30+import java.awt.geom.AffineTransform;
31+import java.awt.image.AffineTransformOp;
32+import java.awt.image.BufferedImage;
33+import java.awt.image.BufferedImageOp;
34+import sun.java2d.SunGraphics2D;
35+import sun.java2d.SurfaceData;
36+import sun.java2d.loops.SurfaceType;
37+import sun.java2d.loops.TransformBlit;
38+import sun.java2d.pipe.DrawImage;
39+
40+public class OGLDrawImage extends DrawImage {
41+
42+ @Override
43+ protected void renderImageXform(SunGraphics2D sg, Image img,
44+ AffineTransform tx, int interpType,
45+ int sx1, int sy1, int sx2, int sy2,
46+ Color bgColor)
47+ {
48+ // punt to the MediaLib-based transformImage() in the superclass if:
49+ // - bicubic interpolation is specified
50+ // - a background color is specified and will be used
51+ // - the source surface is neither a texture nor render-to-texture
52+ // surface, and a non-default interpolation hint is specified
53+ // (we can only control the filtering for texture->surface
54+ // copies)
55+ // REMIND: we should tweak the sw->texture->surface
56+ // transform case to handle filtering appropriately
57+ // (see 4841762)...
58+ // - an appropriate TransformBlit primitive could not be found
59+ if (interpType != AffineTransformOp.TYPE_BICUBIC) {
60+ SurfaceData dstData = sg.surfaceData;
61+ SurfaceData srcData =
62+ dstData.getSourceSurfaceData(img,
63+ sg.TRANSFORM_GENERIC,
64+ sg.imageComp,
65+ bgColor);
66+
67+ if (srcData != null &&
68+ !isBgOperation(srcData, bgColor) &&
69+ (srcData.getSurfaceType() == OGLSurfaceData.OpenGLTexture ||
70+ srcData.getSurfaceType() == OGLSurfaceData.OpenGLSurfaceRTT ||
71+ interpType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR))
72+ {
73+ SurfaceType srcType = srcData.getSurfaceType();
74+ SurfaceType dstType = dstData.getSurfaceType();
75+ TransformBlit blit = TransformBlit.getFromCache(srcType,
76+ sg.imageComp,
77+ dstType);
78+
79+ if (blit != null) {
80+ blit.Transform(srcData, dstData,
81+ sg.composite, sg.getCompClip(),
82+ tx, interpType,
83+ sx1, sy1, 0, 0, sx2-sx1, sy2-sy1);
84+ return;
85+ }
86+ }
87+ }
88+
89+ super.renderImageXform(sg, img, tx, interpType,
90+ sx1, sy1, sx2, sy2, bgColor);
91+ }
92+
93+ @Override
94+ public void transformImage(SunGraphics2D sg, BufferedImage img,
95+ BufferedImageOp op, int x, int y)
96+ {
97+ if (op != null) {
98+ if (op instanceof AffineTransformOp) {
99+ AffineTransformOp atop = (AffineTransformOp) op;
100+ transformImage(sg, img, x, y,
101+ atop.getTransform(),
102+ atop.getInterpolationType());
103+ return;
104+ } else {
105+ if (OGLBufImgOps.renderImageWithOp(sg, img, op, x, y)) {
106+ return;
107+ }
108+ }
109+ img = op.filter(img, null);
110+ }
111+ copyImage(sg, img, x, y, null);
112+ }
113+}
java/pkg/sun/java2d/opengl/OGLGraphicsConfig.java+44−0
@@ -0,0 +1,44 @@
1+/*
2+ * Copyright (c) 2005, 2008, 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+
26+package sun.java2d.opengl;
27+
28+import sun.java2d.SurfaceData;
29+import sun.awt.image.SurfaceManager;
30+import sun.java2d.pipe.hw.AccelGraphicsConfig;
31+
32+/**
33+ * This interface collects the methods that are provided by both
34+ * GLXGraphicsConfig and WGLGraphicsConfig, making it easier to invoke these
35+ * methods directly from OGLSurfaceData.
36+ */
37+interface OGLGraphicsConfig extends
38+ AccelGraphicsConfig, SurfaceManager.ProxiedGraphicsConfig
39+{
40+ OGLContext getContext();
41+ long getNativeConfigInfo();
42+ boolean isCapPresent(int cap);
43+ SurfaceData createManagedSurface(int w, int h, int transparency);
44+}
java/pkg/sun/java2d/opengl/OGLMaskBlit.java+69−0
@@ -0,0 +1,69 @@
1+/*
2+ * Copyright (c) 2003, 2007, 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+
26+package sun.java2d.opengl;
27+
28+import java.awt.Composite;
29+import sun.java2d.SurfaceData;
30+import sun.java2d.loops.CompositeType;
31+import sun.java2d.loops.GraphicsPrimitive;
32+import sun.java2d.loops.GraphicsPrimitiveMgr;
33+import sun.java2d.loops.SurfaceType;
34+import sun.java2d.pipe.Region;
35+import sun.java2d.pipe.BufferedMaskBlit;
36+import static sun.java2d.loops.CompositeType.*;
37+import static sun.java2d.loops.SurfaceType.*;
38+
39+class OGLMaskBlit extends BufferedMaskBlit {
40+
41+ static void register() {
42+ GraphicsPrimitive[] primitives = {
43+ new OGLMaskBlit(IntArgb, SrcOver),
44+ new OGLMaskBlit(IntArgbPre, SrcOver),
45+ new OGLMaskBlit(IntRgb, SrcOver),
46+ new OGLMaskBlit(IntRgb, SrcNoEa),
47+ new OGLMaskBlit(IntBgr, SrcOver),
48+ new OGLMaskBlit(IntBgr, SrcNoEa),
49+ };
50+ GraphicsPrimitiveMgr.register(primitives);
51+ }
52+
53+ private OGLMaskBlit(SurfaceType srcType,
54+ CompositeType compType)
55+ {
56+ super(OGLRenderQueue.getInstance(),
57+ srcType, compType, OGLSurfaceData.OpenGLSurface);
58+ }
59+
60+ @Override
61+ protected void validateContext(SurfaceData dstData,
62+ Composite comp, Region clip)
63+ {
64+ OGLSurfaceData oglDst = (OGLSurfaceData)dstData;
65+ OGLContext.validateContext(oglDst, oglDst,
66+ clip, comp, null, null, null,
67+ OGLContext.NO_CONTEXT_FLAGS);
68+ }
69+}
java/pkg/sun/java2d/opengl/OGLMaskFill.java+75−0
@@ -0,0 +1,75 @@
1+/*
2+ * Copyright (c) 2003, 2007, 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+
26+package sun.java2d.opengl;
27+
28+import java.awt.Composite;
29+import sun.java2d.SunGraphics2D;
30+import sun.java2d.loops.GraphicsPrimitive;
31+import sun.java2d.loops.GraphicsPrimitiveMgr;
32+import sun.java2d.loops.CompositeType;
33+import sun.java2d.loops.SurfaceType;
34+import sun.java2d.pipe.BufferedMaskFill;
35+import static sun.java2d.loops.CompositeType.*;
36+import static sun.java2d.loops.SurfaceType.*;
37+
38+class OGLMaskFill extends BufferedMaskFill {
39+
40+ static void register() {
41+ GraphicsPrimitive[] primitives = {
42+ new OGLMaskFill(AnyColor, SrcOver),
43+ new OGLMaskFill(OpaqueColor, SrcNoEa),
44+ new OGLMaskFill(GradientPaint, SrcOver),
45+ new OGLMaskFill(OpaqueGradientPaint, SrcNoEa),
46+ new OGLMaskFill(LinearGradientPaint, SrcOver),
47+ new OGLMaskFill(OpaqueLinearGradientPaint, SrcNoEa),
48+ new OGLMaskFill(RadialGradientPaint, SrcOver),
49+ new OGLMaskFill(OpaqueRadialGradientPaint, SrcNoEa),
50+ new OGLMaskFill(TexturePaint, SrcOver),
51+ new OGLMaskFill(OpaqueTexturePaint, SrcNoEa),
52+ };
53+ GraphicsPrimitiveMgr.register(primitives);
54+ }
55+
56+ protected OGLMaskFill(SurfaceType srcType, CompositeType compType) {
57+ super(OGLRenderQueue.getInstance(),
58+ srcType, compType, OGLSurfaceData.OpenGLSurface);
59+ }
60+
61+ @Override
62+ protected native void maskFill(int x, int y, int w, int h,
63+ int maskoff, int maskscan, int masklen,
64+ byte[] mask);
65+
66+ @Override
67+ protected void validateContext(SunGraphics2D sg2d,
68+ Composite comp, int ctxflags)
69+ {
70+ OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData;
71+ OGLContext.validateContext(dstData, dstData,
72+ sg2d.getCompClip(), comp,
73+ null, sg2d.paint, sg2d, ctxflags);
74+ }
75+}
java/pkg/sun/java2d/opengl/OGLPaints.java+209−0
@@ -0,0 +1,209 @@
1+/*
2+ * Copyright (c) 2007, 2008, 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+
26+package sun.java2d.opengl;
27+
28+import java.awt.GradientPaint;
29+import java.awt.LinearGradientPaint;
30+import java.awt.MultipleGradientPaint;
31+import java.awt.MultipleGradientPaint.ColorSpaceType;
32+import java.awt.MultipleGradientPaint.CycleMethod;
33+import java.awt.RadialGradientPaint;
34+import java.awt.TexturePaint;
35+import java.awt.image.BufferedImage;
36+import java.util.HashMap;
37+import java.util.Map;
38+import sun.java2d.SunGraphics2D;
39+import sun.java2d.SurfaceData;
40+import sun.java2d.loops.CompositeType;
41+import static sun.java2d.pipe.BufferedPaints.*;
42+import static sun.java2d.opengl.OGLContext.OGLContextCaps.*;
43+
44+abstract class OGLPaints {
45+
46+ /**
47+ * Holds all registered implementations, using the corresponding
48+ * SunGraphics2D.PAINT_* constant as the hash key.
49+ */
50+ private static Map<Integer, OGLPaints> impls =
51+ new HashMap<Integer, OGLPaints>(4, 1.0f);
52+
53+ static {
54+ impls.put(SunGraphics2D.PAINT_GRADIENT, new Gradient());
55+ impls.put(SunGraphics2D.PAINT_LIN_GRADIENT, new LinearGradient());
56+ impls.put(SunGraphics2D.PAINT_RAD_GRADIENT, new RadialGradient());
57+ impls.put(SunGraphics2D.PAINT_TEXTURE, new Texture());
58+ }
59+
60+ /**
61+ * Attempts to locate an implementation corresponding to the paint state
62+ * of the provided SunGraphics2D object. If no implementation can be
63+ * found, or if the paint cannot be accelerated under the conditions
64+ * of the SunGraphics2D, this method returns false; otherwise, returns
65+ * true.
66+ */
67+ static boolean isValid(SunGraphics2D sg2d) {
68+ OGLPaints impl = impls.get(sg2d.paintState);
69+ return (impl != null && impl.isPaintValid(sg2d));
70+ }
71+
72+ /**
73+ * Returns true if this implementation is able to accelerate the
74+ * Paint object associated with, and under the conditions of, the
75+ * provided SunGraphics2D instance; otherwise returns false.
76+ */
77+ abstract boolean isPaintValid(SunGraphics2D sg2d);
78+
79+/************************* GradientPaint support ****************************/
80+
81+ private static class Gradient extends OGLPaints {
82+ private Gradient() {}
83+
84+ /**
85+ * There are no restrictions for accelerating GradientPaint, so
86+ * this method always returns true.
87+ */
88+ @Override
89+ boolean isPaintValid(SunGraphics2D sg2d) {
90+ return true;
91+ }
92+ }
93+
94+/************************** TexturePaint support ****************************/
95+
96+ private static class Texture extends OGLPaints {
97+ private Texture() {}
98+
99+ /**
100+ * Returns true if the given TexturePaint instance can be used by the
101+ * accelerated OGLPaints.Texture implementation. A TexturePaint is
102+ * considered valid if the following conditions are met:
103+ * - the texture image dimensions are power-of-two (or the
104+ * GL_ARB_texture_non_power_of_two extension is present)
105+ * - the texture image can be (or is already) cached in an OpenGL
106+ * texture object
107+ */
108+ @Override
109+ boolean isPaintValid(SunGraphics2D sg2d) {
110+ TexturePaint paint = (TexturePaint)sg2d.paint;
111+ OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData;
112+ BufferedImage bi = paint.getImage();
113+
114+ // see if texture-non-pow2 extension is available
115+ if (!dstData.isTexNonPow2Available()) {
116+ int imgw = bi.getWidth();
117+ int imgh = bi.getHeight();
118+
119+ // verify that the texture image dimensions are pow2
120+ if ((imgw & (imgw - 1)) != 0 || (imgh & (imgh - 1)) != 0) {
121+ return false;
122+ }
123+ }
124+
125+ SurfaceData srcData =
126+ dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,
127+ CompositeType.SrcOver, null);
128+ if (!(srcData instanceof OGLSurfaceData)) {
129+ // REMIND: this is a hack that attempts to cache the system
130+ // memory image from the TexturePaint instance into an
131+ // OpenGL texture...
132+ srcData =
133+ dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,
134+ CompositeType.SrcOver, null);
135+ if (!(srcData instanceof OGLSurfaceData)) {
136+ return false;
137+ }
138+ }
139+
140+ // verify that the source surface is actually a texture
141+ OGLSurfaceData oglData = (OGLSurfaceData)srcData;
142+ if (oglData.getType() != OGLSurfaceData.TEXTURE) {
143+ return false;
144+ }
145+
146+ return true;
147+ }
148+ }
149+
150+/****************** Shared MultipleGradientPaint support ********************/
151+
152+ private static abstract class MultiGradient extends OGLPaints {
153+ protected MultiGradient() {}
154+
155+ /**
156+ * Returns true if the given MultipleGradientPaint instance can be
157+ * used by the accelerated OGLPaints.MultiGradient implementation.
158+ * A MultipleGradientPaint is considered valid if the following
159+ * conditions are met:
160+ * - the number of gradient "stops" is <= MAX_FRACTIONS
161+ * - the destination has support for fragment shaders
162+ */
163+ @Override
164+ boolean isPaintValid(SunGraphics2D sg2d) {
165+ MultipleGradientPaint paint = (MultipleGradientPaint)sg2d.paint;
166+ // REMIND: ugh, this creates garbage; would be nicer if
167+ // we had a MultipleGradientPaint.getNumStops() method...
168+ if (paint.getFractions().length > MULTI_MAX_FRACTIONS) {
169+ return false;
170+ }
171+
172+ OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData;
173+ OGLGraphicsConfig gc = dstData.getOGLGraphicsConfig();
174+ if (!gc.isCapPresent(CAPS_EXT_GRAD_SHADER)) {
175+ return false;
176+ }
177+
178+ return true;
179+ }
180+ }
181+
182+/********************** LinearGradientPaint support *************************/
183+
184+ private static class LinearGradient extends MultiGradient {
185+ private LinearGradient() {}
186+
187+ @Override
188+ boolean isPaintValid(SunGraphics2D sg2d) {
189+ LinearGradientPaint paint = (LinearGradientPaint)sg2d.paint;
190+
191+ if (paint.getFractions().length == 2 &&
192+ paint.getCycleMethod() != CycleMethod.REPEAT &&
193+ paint.getColorSpace() != ColorSpaceType.LINEAR_RGB)
194+ {
195+ // we can delegate to the optimized two-color gradient
196+ // codepath, which does not require fragment shader support
197+ return true;
198+ }
199+
200+ return super.isPaintValid(sg2d);
201+ }
202+ }
203+
204+/********************** RadialGradientPaint support *************************/
205+
206+ private static class RadialGradient extends MultiGradient {
207+ private RadialGradient() {}
208+ }
209+}
java/pkg/sun/java2d/opengl/OGLRenderQueue.java+239−0
@@ -0,0 +1,239 @@
1+/*
2+ * Copyright (c) 2005, 2007, 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+
26+package sun.java2d.opengl;
27+
28+import sun.java2d.pipe.RenderBuffer;
29+import sun.java2d.pipe.RenderQueue;
30+import static sun.java2d.pipe.BufferedOpCodes.*;
31+
32+/**
33+ * OGL-specific implementation of RenderQueue. This class provides a
34+ * single (daemon) thread that is responsible for periodically flushing
35+ * the queue, thus ensuring that only one thread communicates with the native
36+ * OpenGL libraries for the entire process.
37+ */
38+public class OGLRenderQueue extends RenderQueue {
39+
40+ private static OGLRenderQueue theInstance;
41+ private final QueueFlusher flusher;
42+
43+ private OGLRenderQueue() {
44+ flusher = new QueueFlusher();
45+ }
46+
47+ /**
48+ * Returns the single OGLRenderQueue instance. If it has not yet been
49+ * initialized, this method will first construct the single instance
50+ * before returning it.
51+ */
52+ public static synchronized OGLRenderQueue getInstance() {
53+ if (theInstance == null) {
54+ theInstance = new OGLRenderQueue();
55+ }
56+ return theInstance;
57+ }
58+
59+ /**
60+ * Flushes the single OGLRenderQueue instance synchronously. If an
61+ * OGLRenderQueue has not yet been instantiated, this method is a no-op.
62+ * This method is useful in the case of Toolkit.sync(), in which we want
63+ * to flush the OGL pipeline, but only if the OGL pipeline is currently
64+ * enabled. Since this class has few external dependencies, callers need
65+ * not be concerned that calling this method will trigger initialization
66+ * of the OGL pipeline and related classes.
67+ */
68+ public static void sync() {
69+ if (theInstance != null) {
70+ theInstance.lock();
71+ try {
72+ theInstance.ensureCapacity(4);
73+ theInstance.getBuffer().putInt(SYNC);
74+ theInstance.flushNow();
75+ } finally {
76+ theInstance.unlock();
77+ }
78+ }
79+ }
80+
81+ /**
82+ * Disposes the native memory associated with the given native
83+ * graphics config info pointer on the single queue flushing thread.
84+ */
85+ public static void disposeGraphicsConfig(long pConfigInfo) {
86+ OGLRenderQueue rq = getInstance();
87+ rq.lock();
88+ try {
89+ // make sure we make the context associated with the given
90+ // GraphicsConfig current before disposing the native resources
91+ OGLContext.setScratchSurface(pConfigInfo);
92+
93+ RenderBuffer buf = rq.getBuffer();
94+ rq.ensureCapacityAndAlignment(12, 4);
95+ buf.putInt(DISPOSE_CONFIG);
96+ buf.putLong(pConfigInfo);
97+
98+ // this call is expected to complete synchronously, so flush now
99+ rq.flushNow();
100+ } finally {
101+ rq.unlock();
102+ }
103+ }
104+
105+ /**
106+ * Returns true if the current thread is the OGL QueueFlusher thread.
107+ */
108+ public static boolean isQueueFlusherThread() {
109+ return (Thread.currentThread() == getInstance().flusher);
110+ }
111+
112+ public void flushNow() {
113+ // assert lock.isHeldByCurrentThread();
114+ try {
115+ flusher.flushNow();
116+ } catch (Exception e) {
117+ System.err.println("exception in flushNow:");
118+ e.printStackTrace();
119+ }
120+ }
121+
122+ public void flushAndInvokeNow(Runnable r) {
123+ // assert lock.isHeldByCurrentThread();
124+ try {
125+ flusher.flushAndInvokeNow(r);
126+ } catch (Exception e) {
127+ System.err.println("exception in flushAndInvokeNow:");
128+ e.printStackTrace();
129+ }
130+ }
131+
132+ private native void flushBuffer(long buf, int limit);
133+
134+ private void flushBuffer() {
135+ // assert lock.isHeldByCurrentThread();
136+ int limit = buf.position();
137+ if (limit > 0) {
138+ // process the queue
139+ flushBuffer(buf.getAddress(), limit);
140+ }
141+ // reset the buffer position
142+ buf.clear();
143+ // clear the set of references, since we no longer need them
144+ refSet.clear();
145+ }
146+
147+ private class QueueFlusher extends Thread {
148+ private boolean needsFlush;
149+ private Runnable task;
150+ private Error error;
151+
152+ public QueueFlusher() {
153+ super("Java2D Queue Flusher");
154+ setDaemon(true);
155+ setPriority(Thread.MAX_PRIORITY);
156+ start();
157+ }
158+
159+ public synchronized void flushNow() {
160+ // wake up the flusher
161+ needsFlush = true;
162+ notify();
163+
164+ // wait for flush to complete
165+ while (needsFlush) {
166+ try {
167+ wait();
168+ } catch (InterruptedException e) {
169+ }
170+ }
171+
172+ // re-throw any error that may have occurred during the flush
173+ if (error != null) {
174+ throw error;
175+ }
176+ }
177+
178+ public synchronized void flushAndInvokeNow(Runnable task) {
179+ this.task = task;
180+ flushNow();
181+ }
182+
183+ public synchronized void run() {
184+ boolean timedOut = false;
185+ while (true) {
186+ while (!needsFlush) {
187+ try {
188+ timedOut = false;
189+ /*
190+ * Wait until we're woken up with a flushNow() call,
191+ * or the timeout period elapses (so that we can
192+ * flush the queue periodically).
193+ */
194+ wait(100);
195+ /*
196+ * We will automatically flush the queue if the
197+ * following conditions apply:
198+ * - the wait() timed out
199+ * - we can lock the queue (without blocking)
200+ * - there is something in the queue to flush
201+ * Otherwise, just continue (we'll flush eventually).
202+ */
203+ if (!needsFlush && (timedOut = tryLock())) {
204+ if (buf.position() > 0) {
205+ needsFlush = true;
206+ } else {
207+ unlock();
208+ }
209+ }
210+ } catch (InterruptedException e) {
211+ }
212+ }
213+ try {
214+ // reset the throwable state
215+ error = null;
216+ // flush the buffer now
217+ flushBuffer();
218+ // if there's a task, invoke that now as well
219+ if (task != null) {
220+ task.run();
221+ }
222+ } catch (Error e) {
223+ error = e;
224+ } catch (Exception x) {
225+ System.err.println("exception in QueueFlusher:");
226+ x.printStackTrace();
227+ } finally {
228+ if (timedOut) {
229+ unlock();
230+ }
231+ task = null;
232+ // allow the waiting thread to continue
233+ needsFlush = false;
234+ notify();
235+ }
236+ }
237+ }
238+ }
239+}
java/pkg/sun/java2d/opengl/OGLRenderer.java+206−0
@@ -0,0 +1,206 @@
1+/*
2+ * Copyright (c) 2003, 2008, 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+
26+package sun.java2d.opengl;
27+
28+import java.awt.Transparency;
29+import java.awt.geom.Path2D;
30+import sun.java2d.SunGraphics2D;
31+import sun.java2d.loops.GraphicsPrimitive;
32+import sun.java2d.pipe.BufferedRenderPipe;
33+import sun.java2d.pipe.ParallelogramPipe;
34+import sun.java2d.pipe.RenderQueue;
35+import sun.java2d.pipe.SpanIterator;
36+import static sun.java2d.pipe.BufferedOpCodes.*;
37+
38+class OGLRenderer extends BufferedRenderPipe {
39+
40+ OGLRenderer(RenderQueue rq) {
41+ super(rq);
42+ }
43+
44+ @Override
45+ protected void validateContext(SunGraphics2D sg2d) {
46+ int ctxflags =
47+ sg2d.paint.getTransparency() == Transparency.OPAQUE ?
48+ OGLContext.SRC_IS_OPAQUE : OGLContext.NO_CONTEXT_FLAGS;
49+ OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData;
50+ OGLContext.validateContext(dstData, dstData,
51+ sg2d.getCompClip(), sg2d.composite,
52+ null, sg2d.paint, sg2d, ctxflags);
53+ }
54+
55+ @Override
56+ protected void validateContextAA(SunGraphics2D sg2d) {
57+ int ctxflags = OGLContext.NO_CONTEXT_FLAGS;
58+ OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData;
59+ OGLContext.validateContext(dstData, dstData,
60+ sg2d.getCompClip(), sg2d.composite,
61+ null, sg2d.paint, sg2d, ctxflags);
62+ }
63+
64+ void copyArea(SunGraphics2D sg2d,
65+ int x, int y, int w, int h, int dx, int dy)
66+ {
67+ rq.lock();
68+ try {
69+ int ctxflags =
70+ sg2d.surfaceData.getTransparency() == Transparency.OPAQUE ?
71+ OGLContext.SRC_IS_OPAQUE : OGLContext.NO_CONTEXT_FLAGS;
72+ OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData;
73+ OGLContext.validateContext(dstData, dstData,
74+ sg2d.getCompClip(), sg2d.composite,
75+ null, null, null, ctxflags);
76+
77+ rq.ensureCapacity(28);
78+ buf.putInt(COPY_AREA);
79+ buf.putInt(x).putInt(y).putInt(w).putInt(h);
80+ buf.putInt(dx).putInt(dy);
81+ } finally {
82+ rq.unlock();
83+ }
84+ }
85+
86+ @Override
87+ protected native void drawPoly(int[] xPoints, int[] yPoints,
88+ int nPoints, boolean isClosed,
89+ int transX, int transY);
90+
91+ OGLRenderer traceWrap() {
92+ return new Tracer(this);
93+ }
94+
95+ private class Tracer extends OGLRenderer {
96+ private OGLRenderer oglr;
97+ Tracer(OGLRenderer oglr) {
98+ super(oglr.rq);
99+ this.oglr = oglr;
100+ }
101+ public ParallelogramPipe getAAParallelogramPipe() {
102+ final ParallelogramPipe realpipe = oglr.getAAParallelogramPipe();
103+ return new ParallelogramPipe() {
104+ public void fillParallelogram(SunGraphics2D sg2d,
105+ double ux1, double uy1,
106+ double ux2, double uy2,
107+ double x, double y,
108+ double dx1, double dy1,
109+ double dx2, double dy2)
110+ {
111+ GraphicsPrimitive.tracePrimitive("OGLFillAAParallelogram");
112+ realpipe.fillParallelogram(sg2d,
113+ ux1, uy1, ux2, uy2,
114+ x, y, dx1, dy1, dx2, dy2);
115+ }
116+ public void drawParallelogram(SunGraphics2D sg2d,
117+ double ux1, double uy1,
118+ double ux2, double uy2,
119+ double x, double y,
120+ double dx1, double dy1,
121+ double dx2, double dy2,
122+ double lw1, double lw2)
123+ {
124+ GraphicsPrimitive.tracePrimitive("OGLDrawAAParallelogram");
125+ realpipe.drawParallelogram(sg2d,
126+ ux1, uy1, ux2, uy2,
127+ x, y, dx1, dy1, dx2, dy2,
128+ lw1, lw2);
129+ }
130+ };
131+ }
132+ protected void validateContext(SunGraphics2D sg2d) {
133+ oglr.validateContext(sg2d);
134+ }
135+ public void drawLine(SunGraphics2D sg2d,
136+ int x1, int y1, int x2, int y2)
137+ {
138+ GraphicsPrimitive.tracePrimitive("OGLDrawLine");
139+ oglr.drawLine(sg2d, x1, y1, x2, y2);
140+ }
141+ public void drawRect(SunGraphics2D sg2d, int x, int y, int w, int h) {
142+ GraphicsPrimitive.tracePrimitive("OGLDrawRect");
143+ oglr.drawRect(sg2d, x, y, w, h);
144+ }
145+ protected void drawPoly(SunGraphics2D sg2d,
146+ int[] xPoints, int[] yPoints,
147+ int nPoints, boolean isClosed)
148+ {
149+ GraphicsPrimitive.tracePrimitive("OGLDrawPoly");
150+ oglr.drawPoly(sg2d, xPoints, yPoints, nPoints, isClosed);
151+ }
152+ public void fillRect(SunGraphics2D sg2d, int x, int y, int w, int h) {
153+ GraphicsPrimitive.tracePrimitive("OGLFillRect");
154+ oglr.fillRect(sg2d, x, y, w, h);
155+ }
156+ protected void drawPath(SunGraphics2D sg2d,
157+ Path2D.Float p2df, int transx, int transy)
158+ {
159+ GraphicsPrimitive.tracePrimitive("OGLDrawPath");
160+ oglr.drawPath(sg2d, p2df, transx, transy);
161+ }
162+ protected void fillPath(SunGraphics2D sg2d,
163+ Path2D.Float p2df, int transx, int transy)
164+ {
165+ GraphicsPrimitive.tracePrimitive("OGLFillPath");
166+ oglr.fillPath(sg2d, p2df, transx, transy);
167+ }
168+ protected void fillSpans(SunGraphics2D sg2d, SpanIterator si,
169+ int transx, int transy)
170+ {
171+ GraphicsPrimitive.tracePrimitive("OGLFillSpans");
172+ oglr.fillSpans(sg2d, si, transx, transy);
173+ }
174+ public void fillParallelogram(SunGraphics2D sg2d,
175+ double ux1, double uy1,
176+ double ux2, double uy2,
177+ double x, double y,
178+ double dx1, double dy1,
179+ double dx2, double dy2)
180+ {
181+ GraphicsPrimitive.tracePrimitive("OGLFillParallelogram");
182+ oglr.fillParallelogram(sg2d,
183+ ux1, uy1, ux2, uy2,
184+ x, y, dx1, dy1, dx2, dy2);
185+ }
186+ public void drawParallelogram(SunGraphics2D sg2d,
187+ double ux1, double uy1,
188+ double ux2, double uy2,
189+ double x, double y,
190+ double dx1, double dy1,
191+ double dx2, double dy2,
192+ double lw1, double lw2)
193+ {
194+ GraphicsPrimitive.tracePrimitive("OGLDrawParallelogram");
195+ oglr.drawParallelogram(sg2d,
196+ ux1, uy1, ux2, uy2,
197+ x, y, dx1, dy1, dx2, dy2, lw1, lw2);
198+ }
199+ public void copyArea(SunGraphics2D sg2d,
200+ int x, int y, int w, int h, int dx, int dy)
201+ {
202+ GraphicsPrimitive.tracePrimitive("OGLCopyArea");
203+ oglr.copyArea(sg2d, x, y, w, h, dx, dy);
204+ }
205+ }
206+}
java/pkg/sun/java2d/opengl/OGLSurfaceData.java+653−0
@@ -0,0 +1,653 @@
1+/*
2+ * Copyright (c) 2003, 2008, 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+
26+package sun.java2d.opengl;
27+
28+import java.awt.AlphaComposite;
29+import java.awt.GraphicsEnvironment;
30+import java.awt.Rectangle;
31+import java.awt.Transparency;
32+import java.awt.image.ColorModel;
33+import java.awt.image.Raster;
34+import sun.awt.SunHints;
35+import sun.awt.image.PixelConverter;
36+import sun.java2d.pipe.hw.AccelSurface;
37+import sun.java2d.SunGraphics2D;
38+import sun.java2d.SurfaceData;
39+import sun.java2d.SurfaceDataProxy;
40+import sun.java2d.loops.CompositeType;
41+import sun.java2d.loops.GraphicsPrimitive;
42+import sun.java2d.loops.MaskFill;
43+import sun.java2d.loops.SurfaceType;
44+import sun.java2d.pipe.ParallelogramPipe;
45+import sun.java2d.pipe.PixelToParallelogramConverter;
46+import sun.java2d.pipe.RenderBuffer;
47+import sun.java2d.pipe.TextPipe;
48+import static sun.java2d.pipe.BufferedOpCodes.*;
49+import static sun.java2d.opengl.OGLContext.OGLContextCaps.*;
50+
51+/**
52+ * This class describes an OpenGL "surface", that is, a region of pixels
53+ * managed via OpenGL. An OGLSurfaceData can be tagged with one of three
54+ * different SurfaceType objects for the purpose of registering loops, etc.
55+ * This diagram shows the hierarchy of OGL SurfaceTypes:
56+ *
57+ * Any
58+ * / \
59+ * OpenGLSurface OpenGLTexture
60+ * |
61+ * OpenGLSurfaceRTT
62+ *
63+ * OpenGLSurface
64+ * This kind of surface can be rendered to using OpenGL APIs. It is also
65+ * possible to copy an OpenGLSurface to another OpenGLSurface (or to itself).
66+ * This is typically accomplished by calling MakeContextCurrent(dstSD, srcSD)
67+ * and then calling glCopyPixels() (although there are other techniques to
68+ * achieve the same goal).
69+ *
70+ * OpenGLTexture
71+ * This kind of surface cannot be rendered to using OpenGL (in the same sense
72+ * as in OpenGLSurface). However, it is possible to upload a region of pixels
73+ * to an OpenGLTexture object via glTexSubImage2D(). One can also copy a
74+ * surface of type OpenGLTexture to an OpenGLSurface by binding the texture
75+ * to a quad and then rendering it to the destination surface (this process
76+ * is known as "texture mapping").
77+ *
78+ * OpenGLSurfaceRTT
79+ * This kind of surface can be thought of as a sort of hybrid between
80+ * OpenGLSurface and OpenGLTexture, in that one can render to this kind of
81+ * surface as if it were of type OpenGLSurface, but the process of copying
82+ * this kind of surface to another is more like an OpenGLTexture. (Note that
83+ * "RTT" stands for "render-to-texture".)
84+ *
85+ * In addition to these SurfaceType variants, we have also defined some
86+ * constants that describe in more detail the type of underlying OpenGL
87+ * surface. This table helps explain the relationships between those
88+ * "type" constants and their corresponding SurfaceType:
89+ *
90+ * OGL Type Corresponding SurfaceType
91+ * -------- -------------------------
92+ * WINDOW OpenGLSurface
93+ * PBUFFER OpenGLSurface
94+ * TEXTURE OpenGLTexture
95+ * FLIP_BACKBUFFER OpenGLSurface
96+ * FBOBJECT OpenGLSurfaceRTT
97+ */
98+public abstract class OGLSurfaceData extends SurfaceData
99+ implements AccelSurface {
100+
101+ /**
102+ * OGL-specific surface types
103+ *
104+ * @see sun.java2d.pipe.hw.AccelSurface
105+ */
106+ public static final int PBUFFER = RT_PLAIN;
107+ public static final int FBOBJECT = RT_TEXTURE;
108+
109+ /**
110+ * Pixel formats
111+ */
112+ public static final int PF_INT_ARGB = 0;
113+ public static final int PF_INT_ARGB_PRE = 1;
114+ public static final int PF_INT_RGB = 2;
115+ public static final int PF_INT_RGBX = 3;
116+ public static final int PF_INT_BGR = 4;
117+ public static final int PF_INT_BGRX = 5;
118+ public static final int PF_USHORT_565_RGB = 6;
119+ public static final int PF_USHORT_555_RGB = 7;
120+ public static final int PF_USHORT_555_RGBX = 8;
121+ public static final int PF_BYTE_GRAY = 9;
122+ public static final int PF_USHORT_GRAY = 10;
123+ public static final int PF_3BYTE_BGR = 11;
124+
125+ /**
126+ * SurfaceTypes
127+ */
128+ private static final String DESC_OPENGL_SURFACE = "OpenGL Surface";
129+ private static final String DESC_OPENGL_SURFACE_RTT =
130+ "OpenGL Surface (render-to-texture)";
131+ private static final String DESC_OPENGL_TEXTURE = "OpenGL Texture";
132+
133+ static final SurfaceType OpenGLSurface =
134+ SurfaceType.Any.deriveSubType(DESC_OPENGL_SURFACE,
135+ PixelConverter.ArgbPre.instance);
136+ static final SurfaceType OpenGLSurfaceRTT =
137+ OpenGLSurface.deriveSubType(DESC_OPENGL_SURFACE_RTT);
138+ static final SurfaceType OpenGLTexture =
139+ SurfaceType.Any.deriveSubType(DESC_OPENGL_TEXTURE);
140+
141+ /** This will be true if the fbobject system property has been enabled. */
142+ private static boolean isFBObjectEnabled;
143+
144+ /** This will be true if the lcdshader system property has been enabled.*/
145+ private static boolean isLCDShaderEnabled;
146+
147+ /** This will be true if the biopshader system property has been enabled.*/
148+ private static boolean isBIOpShaderEnabled;
149+
150+ /** This will be true if the gradshader system property has been enabled.*/
151+ private static boolean isGradShaderEnabled;
152+
153+ private OGLGraphicsConfig graphicsConfig;
154+ protected int type;
155+ // these fields are set from the native code when the surface is
156+ // initialized
157+ private int nativeWidth, nativeHeight;
158+
159+ protected static OGLRenderer oglRenderPipe;
160+ protected static PixelToParallelogramConverter oglTxRenderPipe;
161+ protected static ParallelogramPipe oglAAPgramPipe;
162+ protected static OGLTextRenderer oglTextPipe;
163+ protected static OGLDrawImage oglImagePipe;
164+
165+ protected native boolean initTexture(long pData,
166+ boolean isOpaque, boolean texNonPow2,
167+ boolean texRect,
168+ int width, int height);
169+ protected native boolean initFBObject(long pData,
170+ boolean isOpaque, boolean texNonPow2,
171+ boolean texRect,
172+ int width, int height);
173+ protected native boolean initFlipBackbuffer(long pData);
174+ protected abstract boolean initPbuffer(long pData, long pConfigInfo,
175+ boolean isOpaque,
176+ int width, int height);
177+
178+ private native int getTextureTarget(long pData);
179+ private native int getTextureID(long pData);
180+
181+ static {
182+ if (!GraphicsEnvironment.isHeadless()) {
183+ // fbobject currently enabled by default; use "false" to disable
184+ String fbo = (String)java.security.AccessController.doPrivileged(
185+ new sun.security.action.GetPropertyAction(
186+ "sun.java2d.opengl.fbobject"));
187+ isFBObjectEnabled = !"false".equals(fbo);
188+
189+ // lcdshader currently enabled by default; use "false" to disable
190+ String lcd = (String)java.security.AccessController.doPrivileged(
191+ new sun.security.action.GetPropertyAction(
192+ "sun.java2d.opengl.lcdshader"));
193+ isLCDShaderEnabled = !"false".equals(lcd);
194+
195+ // biopshader currently enabled by default; use "false" to disable
196+ String biop = (String)java.security.AccessController.doPrivileged(
197+ new sun.security.action.GetPropertyAction(
198+ "sun.java2d.opengl.biopshader"));
199+ isBIOpShaderEnabled = !"false".equals(biop);
200+
201+ // gradshader currently enabled by default; use "false" to disable
202+ String grad = (String)java.security.AccessController.doPrivileged(
203+ new sun.security.action.GetPropertyAction(
204+ "sun.java2d.opengl.gradshader"));
205+ isGradShaderEnabled = !"false".equals(grad);
206+
207+ OGLRenderQueue rq = OGLRenderQueue.getInstance();
208+ oglImagePipe = new OGLDrawImage();
209+ oglTextPipe = new OGLTextRenderer(rq);
210+ oglRenderPipe = new OGLRenderer(rq);
211+ if (GraphicsPrimitive.tracingEnabled()) {
212+ oglTextPipe = oglTextPipe.traceWrap();
213+ //The wrapped oglRenderPipe will wrap the AA pipe as well...
214+ //oglAAPgramPipe = oglRenderPipe.traceWrap();
215+ }
216+ oglAAPgramPipe = oglRenderPipe.getAAParallelogramPipe();
217+ oglTxRenderPipe =
218+ new PixelToParallelogramConverter(oglRenderPipe,
219+ oglRenderPipe,
220+ 1.0, 0.25, true);
221+
222+ OGLBlitLoops.register();
223+ OGLMaskFill.register();
224+ OGLMaskBlit.register();
225+ }
226+ }
227+
228+ protected OGLSurfaceData(OGLGraphicsConfig gc,
229+ ColorModel cm, int type)
230+ {
231+ super(getCustomSurfaceType(type), cm);
232+ this.graphicsConfig = gc;
233+ this.type = type;
234+ setBlitProxyKey(gc.getProxyKey());
235+ }
236+
237+ @Override
238+ public SurfaceDataProxy makeProxyFor(SurfaceData srcData) {
239+ return OGLSurfaceDataProxy.createProxy(srcData, graphicsConfig);
240+ }
241+
242+ /**
243+ * Returns the appropriate SurfaceType corresponding to the given OpenGL
244+ * surface type constant (e.g. TEXTURE -> OpenGLTexture).
245+ */
246+ private static SurfaceType getCustomSurfaceType(int oglType) {
247+ switch (oglType) {
248+ case TEXTURE:
249+ return OpenGLTexture;
250+ case FBOBJECT:
251+ return OpenGLSurfaceRTT;
252+ case PBUFFER:
253+ default:
254+ return OpenGLSurface;
255+ }
256+ }
257+

396 more lines aren’t shown here.

java/pkg/sun/java2d/opengl/OGLSurfaceDataProxy.java+81−0

This diff is large: its 82 lines aren’t shown here.

java/pkg/sun/java2d/opengl/OGLTextRenderer.java+71−0

This diff is large: its 72 lines aren’t shown here.

java/pkg/sun/java2d/opengl/OGLUtilities.java+338−0

This diff is large: its 339 lines aren’t shown here.

java/pkg/sun/java2d/opengl/mkfile+21−0

This diff is large: its 22 lines aren’t shown here.

java/pkg/sun/java2d/pipe/AAShapePipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/AAShapePipe.java+215−0

This diff is large: its 216 lines aren’t shown here.

java/pkg/sun/java2d/pipe/AATextRenderer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/AATextRenderer.java+45−0

This diff is large: its 46 lines aren’t shown here.

java/pkg/sun/java2d/pipe/AATileGenerator.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/AATileGenerator.java+111−0

This diff is large: its 112 lines aren’t shown here.

java/pkg/sun/java2d/pipe/AlphaColorPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/AlphaColorPipe.java+90−0

This diff is large: its 91 lines aren’t shown here.

java/pkg/sun/java2d/pipe/AlphaPaintPipe$TileContext.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/AlphaPaintPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/AlphaPaintPipe.java+206−0

This diff is large: its 207 lines aren’t shown here.

java/pkg/sun/java2d/pipe/BufferedBufImgOps.java+393−0

This diff is large: its 394 lines aren’t shown here.

java/pkg/sun/java2d/pipe/BufferedContext.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/BufferedContext.java+470−0

This diff is large: its 471 lines aren’t shown here.

java/pkg/sun/java2d/pipe/BufferedMaskBlit.java+163−0

This diff is large: its 164 lines aren’t shown here.

java/pkg/sun/java2d/pipe/BufferedMaskFill.java+153−0

This diff is large: its 154 lines aren’t shown here.

java/pkg/sun/java2d/pipe/BufferedOpCodes.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/BufferedOpCodes.java+99−0

This diff is large: its 100 lines aren’t shown here.

java/pkg/sun/java2d/pipe/BufferedPaints.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/BufferedPaints.java+533−0

This diff is large: its 534 lines aren’t shown here.

java/pkg/sun/java2d/pipe/BufferedRenderPipe$1.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/BufferedRenderPipe$AAParallelogramPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/BufferedRenderPipe$BufferedDrawHandler.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/BufferedRenderPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/BufferedRenderPipe.java+601−0

This diff is large: its 602 lines aren’t shown here.

java/pkg/sun/java2d/pipe/BufferedTextPipe.java+168−0

This diff is large: its 169 lines aren’t shown here.

java/pkg/sun/java2d/pipe/CompositePipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/CompositePipe.java+50−0

This diff is large: its 51 lines aren’t shown here.

java/pkg/sun/java2d/pipe/DrawImage.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/DrawImage.java+1110−0

This diff is large: its 1111 lines aren’t shown here.

java/pkg/sun/java2d/pipe/DrawImagePipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/DrawImagePipe.java+86−0

This diff is large: its 87 lines aren’t shown here.

java/pkg/sun/java2d/pipe/GeneralCompositePipe$TileContext.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/GeneralCompositePipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/GeneralCompositePipe.java+154−0

This diff is large: its 155 lines aren’t shown here.

java/pkg/sun/java2d/pipe/GlyphListLoopPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/GlyphListLoopPipe.java+60−0

This diff is large: its 61 lines aren’t shown here.

java/pkg/sun/java2d/pipe/GlyphListPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/GlyphListPipe.java+147−0

This diff is large: its 148 lines aren’t shown here.

java/pkg/sun/java2d/pipe/LCDTextRenderer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/LCDTextRenderer.java+44−0

This diff is large: its 45 lines aren’t shown here.

java/pkg/sun/java2d/pipe/LoopBasedPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/LoopBasedPipe.java+37−0

This diff is large: its 38 lines aren’t shown here.

java/pkg/sun/java2d/pipe/LoopPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/LoopPipe.java+378−0

This diff is large: its 379 lines aren’t shown here.

java/pkg/sun/java2d/pipe/NullPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/NullPipe.java+155−0

This diff is large: its 156 lines aren’t shown here.

java/pkg/sun/java2d/pipe/OutlineTextRenderer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/OutlineTextRenderer.java+145−0

This diff is large: its 146 lines aren’t shown here.

java/pkg/sun/java2d/pipe/ParallelogramPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/ParallelogramPipe.java+76−0

This diff is large: its 77 lines aren’t shown here.

java/pkg/sun/java2d/pipe/PixelDrawPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/PixelDrawPipe.java+67−0

This diff is large: its 68 lines aren’t shown here.

java/pkg/sun/java2d/pipe/PixelFillPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/PixelFillPipe.java+61−0

This diff is large: its 62 lines aren’t shown here.

java/pkg/sun/java2d/pipe/PixelToParallelogramConverter.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/PixelToParallelogramConverter.java+429−0

This diff is large: its 430 lines aren’t shown here.

java/pkg/sun/java2d/pipe/PixelToShapeConverter.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/PixelToShapeConverter.java+133−0

This diff is large: its 134 lines aren’t shown here.

java/pkg/sun/java2d/pipe/Region$ImmutableRegion.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/Region.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/Region.java+1255−0

This diff is large: its 1256 lines aren’t shown here.

java/pkg/sun/java2d/pipe/RegionClipSpanIterator.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/RegionClipSpanIterator.java+392−0

This diff is large: its 393 lines aren’t shown here.

java/pkg/sun/java2d/pipe/RegionIterator.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/RegionIterator.java+101−0

This diff is large: its 102 lines aren’t shown here.

java/pkg/sun/java2d/pipe/RegionSpanIterator.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/RegionSpanIterator.java+210−0

This diff is large: its 211 lines aren’t shown here.

java/pkg/sun/java2d/pipe/RenderBuffer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/RenderBuffer.java+294−0

This diff is large: its 295 lines aren’t shown here.

java/pkg/sun/java2d/pipe/RenderQueue.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/RenderQueue.java+223−0

This diff is large: its 224 lines aren’t shown here.

java/pkg/sun/java2d/pipe/RenderingEngine$1.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/RenderingEngine$Tracer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/RenderingEngine.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/RenderingEngine.java+482−0

This diff is large: its 483 lines aren’t shown here.

java/pkg/sun/java2d/pipe/ShapeDrawPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/ShapeDrawPipe.java+40−0

This diff is large: its 41 lines aren’t shown here.

java/pkg/sun/java2d/pipe/ShapeSpanIterator.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/ShapeSpanIterator.java+201−0

This diff is large: its 202 lines aren’t shown here.

java/pkg/sun/java2d/pipe/SolidTextRenderer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/SolidTextRenderer.java+44−0

This diff is large: its 45 lines aren’t shown here.

java/pkg/sun/java2d/pipe/SpanClipRenderer$SCRcontext.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/SpanClipRenderer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/SpanClipRenderer.java+141−0

This diff is large: its 142 lines aren’t shown here.

java/pkg/sun/java2d/pipe/SpanIterator.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/SpanIterator.java+95−0

This diff is large: its 96 lines aren’t shown here.

java/pkg/sun/java2d/pipe/SpanShapeRenderer$Composite.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/SpanShapeRenderer$Simple.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/SpanShapeRenderer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/SpanShapeRenderer.java+216−0

This diff is large: its 217 lines aren’t shown here.

java/pkg/sun/java2d/pipe/TextPipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/TextPipe.java+49−0

This diff is large: its 50 lines aren’t shown here.

java/pkg/sun/java2d/pipe/TextRenderer.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/TextRenderer.java+98−0

This diff is large: its 99 lines aren’t shown here.

java/pkg/sun/java2d/pipe/ValidatePipe.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/ValidatePipe.java+241−0

This diff is large: its 242 lines aren’t shown here.

java/pkg/sun/java2d/pipe/hw/AccelDeviceEventListener.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/hw/AccelDeviceEventListener.java+59−0

This diff is large: its 60 lines aren’t shown here.

java/pkg/sun/java2d/pipe/hw/AccelDeviceEventNotifier.java+167−0

This diff is large: its 168 lines aren’t shown here.

java/pkg/sun/java2d/pipe/hw/AccelGraphicsConfig.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/hw/AccelGraphicsConfig.java+95−0

This diff is large: its 96 lines aren’t shown here.

java/pkg/sun/java2d/pipe/hw/AccelSurface.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/hw/AccelSurface.java+136−0

This diff is large: its 137 lines aren’t shown here.

java/pkg/sun/java2d/pipe/hw/AccelTypedVolatileImage.java+74−0

This diff is large: its 75 lines aren’t shown here.

java/pkg/sun/java2d/pipe/hw/BufferedContextProvider.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/hw/BufferedContextProvider.java+45−0

This diff is large: its 46 lines aren’t shown here.

java/pkg/sun/java2d/pipe/hw/ContextCapabilities.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/hw/ContextCapabilities.java+128−0

This diff is large: its 129 lines aren’t shown here.

java/pkg/sun/java2d/pipe/hw/ExtendedBufferCapabilities$VSyncType.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/hw/ExtendedBufferCapabilities.class+0−0

Binary file not shown.

java/pkg/sun/java2d/pipe/hw/ExtendedBufferCapabilities.java+154−0

This diff is large: its 155 lines aren’t shown here.

java/pkg/sun/java2d/pipe/hw/mkfile+15−0

This diff is large: its 16 lines aren’t shown here.

java/pkg/sun/java2d/pipe/mkfile+56−0

This diff is large: its 57 lines aren’t shown here.

java/pkg/sun/java2d/pisces/Curve.java+290−0

This diff is large: its 291 lines aren’t shown here.

java/pkg/sun/java2d/pisces/Dasher.java+575−0

This diff is large: its 576 lines aren’t shown here.

java/pkg/sun/java2d/pisces/Helpers.java+458−0

This diff is large: its 459 lines aren’t shown here.

java/pkg/sun/java2d/pisces/META-INF/mkfile+6−0

This diff is large: its 7 lines aren’t shown here.

java/pkg/sun/java2d/pisces/META-INF/services/mkfile+2−0

This diff is large: its 3 lines aren’t shown here.

java/pkg/sun/java2d/pisces/META-INF/services/sun.java2d.pipe.RenderingEngine+2−0

This diff is large: its 3 lines aren’t shown here.

java/pkg/sun/java2d/pisces/PiscesCache.java+186−0

This diff is large: its 187 lines aren’t shown here.

java/pkg/sun/java2d/pisces/PiscesRenderingEngine.java+656−0

This diff is large: its 657 lines aren’t shown here.

java/pkg/sun/java2d/pisces/PiscesTileGenerator.java+252−0

This diff is large: its 253 lines aren’t shown here.

java/pkg/sun/java2d/pisces/Renderer.java+571−0

This diff is large: its 572 lines aren’t shown here.

java/pkg/sun/java2d/pisces/Stroker.java+1223−0

This diff is large: its 1224 lines aren’t shown here.

java/pkg/sun/java2d/pisces/TransformingPathConsumer2D.java+393−0

This diff is large: its 394 lines aren’t shown here.

java/pkg/sun/java2d/pisces/mkfile+20−0

This diff is large: its 21 lines aren’t shown here.