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
26package 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 */
32public 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
26package sun.java2d;
27
28import sun.java2d.pipe.hw.*;
29
30/**
31 * Classes implementing this interface provide access to their
32 * destination surfaces.
33 */
34public 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
26package sun.java2d;
27
28import java.lang.ref.Reference;
29import java.lang.ref.ReferenceQueue;
30import java.lang.ref.PhantomReference;
31import java.lang.ref.WeakReference;
32import java.util.ArrayList;
33import 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 */
49public 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
26package sun.java2d;
27
28/**
29 * This class is used to hold the resource to be
30 * disposed.
31 */
32public 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
26package sun.java2d;
27
28/**
29 * This is an interface which should be implemented by
30 * the classes which use Disposer.
31 */
32public 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
26package sun.java2d;
27
28import sun.awt.FontConfiguration;
29
30/**
31 * Font support for graphics environment
32 */
33public 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
26package sun.java2d;
27
28import java.awt.GraphicsEnvironment;
29import java.awt.GraphicsDevice;
30import java.awt.Graphics2D;
31import java.awt.HeadlessException;
32import java.awt.image.BufferedImage;
33import java.awt.Font;
34import java.text.AttributedCharacterIterator;
35import java.awt.print.PrinterJob;
36import java.util.Map;
37import java.util.Hashtable;
38import java.util.Locale;
39import java.util.Vector;
40import java.util.StringTokenizer;
41import java.util.ResourceBundle;
42import java.util.MissingResourceException;
43import java.io.IOException;
44import java.io.FilenameFilter;
45import java.io.File;
46import java.util.NoSuchElementException;
47import sun.awt.FontConfiguration;
48import java.util.TreeMap;
49import java.util.Set;
50import java.awt.font.TextAttribute;
51import java.io.InputStream;
52import java.io.FileInputStream;
53import java.io.BufferedInputStream;
54import java.util.Properties;
55import java.awt.Point;
56import java.awt.Rectangle;
57
58/**
59 * Headless decorator implementation of a SunGraphicsEnvironment
60 */
61
62public 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
26package 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 */
37public 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
26package sun.java2d;
27
28import java.awt.Rectangle;
29import java.awt.image.Raster;
30import java.awt.image.ColorModel;
31import java.awt.GraphicsConfiguration;
32
33import sun.java2d.StateTrackable.State;
34import sun.java2d.loops.SurfaceType;
35import 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 */
42public 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
26package sun.java2d;
27
28import java.util.Comparator;
29import java.util.Collections;
30import java.util.Iterator;
31import java.util.List;
32import 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 */
39public 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
26package 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 */
148public 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
26package sun.java2d;
27
28import sun.java2d.StateTrackable.State;
29import 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 */
41public 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
26package 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 */
63public 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
26package sun.java2d;
27
28import java.awt.Composite;
29import java.awt.CompositeContext;
30import java.awt.AlphaComposite;
31import java.awt.image.ColorModel;
32import java.awt.image.BufferedImage;
33import java.awt.image.Raster;
34import java.awt.image.WritableRaster;
35import sun.awt.image.BufImgSurfaceData;
36import sun.java2d.loops.XORComposite;
37import sun.java2d.loops.CompositeType;
38import sun.java2d.loops.Blit;
39
40public 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
26package sun.java2d;
27
28import java.awt.Graphics;
29import java.awt.Graphics2D;
30import java.awt.RenderingHints;
31import java.awt.RenderingHints.Key;
32import java.awt.geom.Area;
33import java.awt.geom.AffineTransform;
34import java.awt.geom.NoninvertibleTransformException;
35import java.awt.AlphaComposite;
36import java.awt.BasicStroke;
37import java.awt.image.BufferedImage;
38import java.awt.image.BufferedImageOp;
39import java.awt.image.RenderedImage;
40import java.awt.image.renderable.RenderableImage;
41import java.awt.image.renderable.RenderContext;
42import java.awt.image.AffineTransformOp;
43import java.awt.image.Raster;
44import java.awt.image.WritableRaster;
45import java.awt.Image;
46import java.awt.Composite;
47import java.awt.Color;
48import java.awt.image.ColorModel;
49import java.awt.GraphicsConfiguration;
50import java.awt.Paint;
51import java.awt.GradientPaint;
52import java.awt.LinearGradientPaint;
53import java.awt.RadialGradientPaint;
54import java.awt.TexturePaint;
55import java.awt.geom.Rectangle2D;
56import java.awt.geom.PathIterator;
57import java.awt.geom.GeneralPath;
58import java.awt.Shape;
59import java.awt.Stroke;
60import java.awt.FontMetrics;
61import java.awt.Rectangle;
62import java.text.AttributedCharacterIterator;
63import java.awt.Font;
64import java.awt.image.ImageObserver;
65import java.awt.Transparency;
66import java.awt.font.GlyphVector;
67import java.awt.font.TextLayout;
68import sun.font.FontDesignMetrics;
69import sun.font.FontUtilities;
70import sun.java2d.pipe.PixelDrawPipe;
71import sun.java2d.pipe.PixelFillPipe;
72import sun.java2d.pipe.ShapeDrawPipe;
73import sun.java2d.pipe.ValidatePipe;
74import sun.java2d.pipe.ShapeSpanIterator;
75import sun.java2d.pipe.Region;
76import sun.java2d.pipe.TextPipe;
77import sun.java2d.pipe.DrawImagePipe;
78import sun.java2d.pipe.LoopPipe;
79import sun.java2d.loops.FontInfo;
80import sun.java2d.loops.RenderLoops;
81import sun.java2d.loops.CompositeType;
82import sun.java2d.loops.SurfaceType;
83import sun.java2d.loops.Blit;
84import sun.java2d.loops.MaskFill;
85import sun.font.FontManager;
86import java.awt.font.FontRenderContext;
87import sun.java2d.loops.XORComposite;
88import sun.awt.ConstrainableGraphics;
89import sun.awt.SunHints;
90import java.util.Map;
91import java.util.Iterator;
92import sun.java2d.DestSurfaceProvider;
93import 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 */
104public 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
26package sun.java2d;
27
28import java.awt.Color;
29import java.awt.Font;
30import java.awt.Graphics2D;
31import java.awt.GraphicsConfiguration;
32import java.awt.GraphicsDevice;
33import java.awt.GraphicsEnvironment;
34import java.awt.Insets;
35import java.awt.Rectangle;
36import java.awt.Toolkit;
37import java.awt.font.TextAttribute;
38import java.awt.image.BufferedImage;
39import java.awt.peer.ComponentPeer;
40import java.io.BufferedReader;
41import java.io.File;
42import java.io.FileInputStream;
43import java.io.FilenameFilter;
44import java.io.InputStreamReader;
45import java.io.IOException;
46import java.text.AttributedCharacterIterator;
47import java.util.ArrayList;
48import java.util.HashSet;
49import java.util.Iterator;
50import java.util.Locale;
51import java.util.Map;
52import java.util.NoSuchElementException;
53import java.util.Set;
54import java.util.StringTokenizer;
55import java.util.TreeMap;
56import java.util.Vector;
57import java.util.concurrent.ConcurrentHashMap;
58import sun.awt.AppContext;
59import sun.awt.DisplayChangedListener;
60import sun.awt.FontConfiguration;
61import sun.awt.SunDisplayChanger;
62import sun.font.CompositeFontDescriptor;
63import sun.font.Font2D;
64import sun.font.FontManager;
65import sun.font.FontManagerFactory;
66import sun.font.FontManagerForSGE;
67import 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 */
76public 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
26package 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 */
33public 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
26package sun.java2d;
27
28import java.awt.Color;
29import java.awt.Rectangle;
30import java.awt.Transparency;
31import java.awt.GraphicsConfiguration;
32import java.awt.Image;
33import java.awt.image.ColorModel;
34import java.awt.image.IndexColorModel;
35import java.awt.image.Raster;
36
37import sun.java2d.loops.RenderCache;
38import sun.java2d.loops.RenderLoops;
39import sun.java2d.loops.CompositeType;
40import sun.java2d.loops.SurfaceType;
41import sun.java2d.loops.MaskFill;
42import sun.java2d.loops.DrawLine;
43import sun.java2d.loops.FillRect;
44import sun.java2d.loops.DrawRect;
45import sun.java2d.loops.DrawPolygons;
46import sun.java2d.loops.DrawPath;
47import sun.java2d.loops.FillPath;
48import sun.java2d.loops.FillSpans;
49import sun.java2d.loops.FillParallelogram;
50import sun.java2d.loops.DrawParallelogram;
51import sun.java2d.loops.FontInfo;
52import sun.java2d.loops.DrawGlyphList;
53import sun.java2d.loops.DrawGlyphListAA;
54import sun.java2d.loops.DrawGlyphListLCD;
55import sun.java2d.pipe.LoopPipe;
56import sun.java2d.pipe.ShapeDrawPipe;
57import sun.java2d.pipe.ParallelogramPipe;
58import sun.java2d.pipe.CompositePipe;
59import sun.java2d.pipe.GeneralCompositePipe;
60import sun.java2d.pipe.SpanClipRenderer;
61import sun.java2d.pipe.SpanShapeRenderer;
62import sun.java2d.pipe.AAShapePipe;
63import sun.java2d.pipe.AlphaPaintPipe;
64import sun.java2d.pipe.AlphaColorPipe;
65import sun.java2d.pipe.PixelToShapeConverter;
66import sun.java2d.pipe.PixelToParallelogramConverter;
67import sun.java2d.pipe.TextPipe;
68import sun.java2d.pipe.TextRenderer;
69import sun.java2d.pipe.AATextRenderer;
70import sun.java2d.pipe.LCDTextRenderer;
71import sun.java2d.pipe.SolidTextRenderer;
72import sun.java2d.pipe.OutlineTextRenderer;
73import sun.java2d.pipe.DrawImagePipe;
74import sun.java2d.pipe.DrawImage;
75import sun.awt.SunHints;
76import sun.awt.image.SurfaceManager;
77import 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 */
101public 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
26package sun.java2d;
27
28import java.awt.Color;
29import java.awt.Rectangle;
30import java.awt.AlphaComposite;
31import java.awt.GraphicsEnvironment;
32
33import sun.awt.DisplayChangedListener;
34import sun.java2d.StateTrackable.State;
35import sun.java2d.loops.CompositeType;
36import sun.java2d.loops.SurfaceType;
37import sun.java2d.loops.Blit;
38import sun.java2d.loops.BlitBg;
39import sun.awt.image.SurfaceManager;
40import sun.awt.image.SurfaceManager.FlushableCacheData;
41
42import java.security.AccessController;
43import 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 */
66public 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
26package sun.java2d;
27
28import sun.awt.image.SunVolatileImage;
29import 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 */
40public 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
26package sun.java2d.cmm;
27
28import java.awt.color.ColorSpace;
29import java.awt.color.ICC_Profile;
30import java.awt.color.CMMException;
31import java.awt.image.BufferedImage;
32import java.awt.image.Raster;
33import java.awt.image.WritableRaster;
34import java.security.AccessController;
35import java.security.PrivilegedAction;
36import sun.security.action.GetPropertyAction;
37import java.util.ServiceLoader;
38
39public 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
26package sun.java2d.cmm;
27
28import java.awt.image.BufferedImage;
29import java.awt.image.Raster;
30import java.awt.image.WritableRaster;
31
32public 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
26package sun.java2d.cmm;
27
28import java.awt.color.ICC_Profile;
29
30/* Pluggable CMM interface */
31
32public 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
26package sun.java2d.cmm;
27
28import java.awt.color.ProfileDataException;
29
30/**
31 * An interface to allow the ProfileDeferralMgr to activate a
32 * deferred profile.
33 */
34public 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
26package sun.java2d.cmm;
27
28import java.io.InputStream;
29import 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 */
38public 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
26package sun.java2d.cmm;
27
28import java.awt.color.ProfileDataException;
29import 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 */
40public 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
26package sun.java2d.cmm.lcms;
27
28import java.awt.color.ColorSpace;
29import java.awt.color.ICC_Profile;
30import java.awt.color.CMMException;
31import sun.java2d.cmm.ColorTransform;
32import sun.java2d.cmm.PCMM;
33import sun.java2d.cmm.lcms.LCMS;
34import sun.java2d.cmm.lcms.LCMSTransform;
35
36public 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
26package sun.java2d.cmm.lcms;
27
28import java.awt.Graphics2D;
29import java.awt.image.BufferedImage;
30import java.awt.image.ComponentColorModel;
31import java.awt.image.Raster;
32import java.awt.image.WritableRaster;
33import java.awt.image.SinglePixelPackedSampleModel;
34import java.awt.image.ComponentSampleModel;
35import java.awt.image.DataBuffer;
36import java.awt.image.DataBufferByte;
37import java.awt.image.DataBufferUShort;
38import java.awt.image.DataBufferInt;
39import java.awt.image.ColorModel;
40import sun.awt.image.ByteComponentRaster;
41import sun.awt.image.ShortComponentRaster;
42import sun.awt.image.IntegerComponentRaster;
43
44
45class 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
36package sun.java2d.cmm.lcms;
37
38import java.awt.color.ICC_Profile;
39import java.awt.color.ProfileDataException;
40import java.awt.color.CMMException;
41import java.awt.color.ColorSpace;
42import java.awt.image.BufferedImage;
43import java.awt.image.Raster;
44import java.awt.image.WritableRaster;
45import java.awt.image.ColorModel;
46import java.awt.image.DirectColorModel;
47import java.awt.image.ComponentColorModel;
48import java.awt.image.SampleModel;
49import java.awt.image.DataBuffer;
50import java.awt.image.SinglePixelPackedSampleModel;
51import java.awt.image.ComponentSampleModel;
52import sun.java2d.cmm.*;
53import sun.java2d.cmm.lcms.*;
54
55
56public 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
3DIRS=\
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
2sun.java2d.cmm.lcms.LCMS
java/pkg/sun/java2d/cmm/lcms/mkfile+14−0
@@ -0,0 +1,14 @@
1<../../../../../../mkconfig
2
3DIRS=\
4 META-INF\
5
6TARG=\
7 LCMS.dis\
8 LCMSImageLayout.dis\
9 LCMSTransform.dis\
10
11DISBIN=$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
3DIRS=\
4 lcms\
5
6TARG=\
7 CMSManager.dis\
8 ColorTransform.dis\
9 PCMM.dis\
10 ProfileActivator.dis\
11 ProfileDeferralInfo.dis\
12 ProfileDeferralMgr.dis\
13
14DISBIN=$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
26package sun.java2d.loops;
27
28import java.awt.Composite;
29import java.awt.CompositeContext;
30import java.awt.RenderingHints;
31import java.awt.image.ColorModel;
32import java.awt.image.Raster;
33import java.awt.image.WritableRaster;
34import java.lang.ref.WeakReference;
35import sun.java2d.loops.GraphicsPrimitive;
36import sun.java2d.SurfaceData;
37import sun.java2d.pipe.Region;
38import 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
51public 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
26package sun.java2d.loops;
27
28import java.awt.Font;
29import java.awt.Color;
30import java.awt.Composite;
31import java.awt.AlphaComposite;
32import java.awt.Transparency;
33import java.awt.image.ColorModel;
34import java.awt.image.WritableRaster;
35import java.awt.image.BufferedImage;
36import sun.awt.image.BufImgSurfaceData;
37import sun.java2d.loops.GraphicsPrimitive;
38import sun.java2d.SurfaceData;
39import sun.java2d.SunGraphics2D;
40import 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 */
55public 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
26package sun.java2d.loops;
27
28import java.awt.image.BufferedImage;
29import java.awt.AlphaComposite;
30import 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 */
54public 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
31package sun.java2d.loops;
32
33import java.awt.Composite;
34import java.awt.Rectangle;
35import java.awt.image.ColorModel;
36import java.awt.image.DataBuffer;
37import java.awt.image.Raster;
38import java.awt.image.WritableRaster;
39import sun.awt.image.IntegerComponentRaster;
40import sun.java2d.SurfaceData;
41import sun.java2d.pipe.Region;
42import 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 */
49public 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 */
109class 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 */
164class 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 */
219class 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
26package sun.java2d.loops;
27
28import sun.java2d.loops.GraphicsPrimitive;
29import sun.java2d.pipe.Region;
30import sun.java2d.SunGraphics2D;
31import sun.java2d.SurfaceData;
32import 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 */
40public 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
26package sun.java2d.loops;
27
28import sun.java2d.loops.GraphicsPrimitive;
29import sun.java2d.pipe.Region;
30import sun.java2d.SunGraphics2D;
31import sun.java2d.SurfaceData;
32import 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 */
40public 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
26package sun.java2d.loops;
27
28import sun.java2d.loops.GraphicsPrimitive;
29import sun.java2d.pipe.Region;
30import sun.java2d.SunGraphics2D;
31import sun.java2d.SurfaceData;
32import 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 */
40public 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
30package sun.java2d.loops;
31
32import sun.java2d.loops.GraphicsPrimitive;
33import java.awt.Color;
34import java.awt.image.ColorModel;
35import java.awt.image.Raster;
36import sun.java2d.SunGraphics2D;
37import 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 */
45public 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
30package sun.java2d.loops;
31
32import sun.java2d.loops.GraphicsPrimitive;
33import sun.java2d.SunGraphics2D;
34import 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 */
43public 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
26package sun.java2d.loops;
27
28import sun.java2d.loops.GraphicsPrimitive;
29import sun.java2d.SunGraphics2D;
30import sun.java2d.SurfaceData;
31import 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 */
39public 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
30package sun.java2d.loops;
31
32import sun.java2d.loops.GraphicsPrimitive;
33import sun.java2d.SunGraphics2D;
34import 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 */
42public 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
30package sun.java2d.loops;
31
32import sun.java2d.loops.GraphicsPrimitive;
33import java.awt.Color;
34import java.awt.image.ColorModel;
35import java.awt.image.Raster;
36import sun.java2d.SunGraphics2D;
37import 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 */
45public 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
30package sun.java2d.loops;
31
32import sun.java2d.loops.GraphicsPrimitive;
33import sun.java2d.SunGraphics2D;
34import 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 */
41public 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
26package sun.java2d.loops;
27
28import sun.java2d.loops.GraphicsPrimitive;
29import sun.java2d.SunGraphics2D;
30import sun.java2d.SurfaceData;
31import 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 */
39public 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
30package sun.java2d.loops;
31
32import sun.java2d.loops.GraphicsPrimitive;
33import java.awt.Color;
34import java.awt.image.ColorModel;
35import java.awt.image.Raster;
36import sun.java2d.SunGraphics2D;
37import 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 */
45public 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
31package sun.java2d.loops;
32
33import sun.java2d.loops.GraphicsPrimitive;
34import sun.java2d.pipe.SpanIterator;
35import java.awt.Color;
36import java.awt.image.ColorModel;
37import java.awt.image.Raster;
38import sun.java2d.SunGraphics2D;
39import 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 */
46public 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
26package sun.java2d.loops;
27
28import java.awt.Font;
29import java.awt.geom.AffineTransform;
30
31import sun.font.Font2D;
32import sun.font.FontStrike;
33import 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 */
46public 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
30package sun.java2d.loops;
31
32import java.awt.image.WritableRaster;
33import java.awt.image.DataBuffer;
34import java.awt.image.ColorModel;
35import java.awt.geom.Path2D;
36import java.awt.geom.PathIterator;
37import java.awt.geom.AffineTransform;
38import sun.java2d.pipe.Region;
39import sun.java2d.pipe.SpanIterator;
40import sun.java2d.SunGraphics2D;
41import sun.java2d.SurfaceData;
42import sun.java2d.loops.ProcessPath;
43import 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
51public 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
650class 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
670class 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
699class 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
717class 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
737class 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
761class 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
788class 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
808class 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
824class 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
844class 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
862class 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
882class 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
906class 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
933class 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
952class 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
968class 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
983class 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
998abstract 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
1008class 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
1020abstract 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
30package sun.java2d.loops;
31
32import java.awt.image.BufferedImage;
33import java.awt.AlphaComposite;
34import java.awt.Rectangle;
35import sun.awt.image.BufImgSurfaceData;
36import sun.java2d.SurfaceData;
37import sun.java2d.pipe.Region;
38import java.lang.reflect.Field;
39import java.util.StringTokenizer;
40import java.util.Iterator;
41import java.util.HashMap;
42import java.util.Map;
43import java.io.PrintStream;
44import java.io.OutputStream;
45import java.io.FileOutputStream;
46import java.io.FileNotFoundException;
47import java.security.AccessController;
48import java.security.PrivilegedAction;
49import sun.security.action.GetPropertyAction;
50
51/**
52 * defines interface for primitives which can be placed into
53 * the graphic component manager framework
54 */
55public 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
30package sun.java2d.loops;
31
32import java.util.Comparator;
33import java.util.Arrays;
34import 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 */
41public 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
26package 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 */
42public 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
26package sun.java2d.loops;
27
28import java.awt.Composite;
29import java.lang.ref.WeakReference;
30import sun.java2d.loops.GraphicsPrimitive;
31import sun.java2d.SurfaceData;
32import 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
49public 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
26package sun.java2d.loops;
27
28import java.awt.Paint;
29import java.awt.PaintContext;
30import java.awt.Composite;
31import java.awt.Rectangle;
32import java.awt.image.ColorModel;
33import java.awt.image.BufferedImage;
34import java.awt.image.WritableRaster;
35import sun.awt.image.BufImgSurfaceData;
36import sun.java2d.loops.GraphicsPrimitive;
37import sun.java2d.SunGraphics2D;
38import 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 */
50public 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
26package sun.java2d.loops;
27
28import java.awt.geom.Path2D;
29import java.awt.geom.PathIterator;
30import java.awt.geom.QuadCurve2D;
31import sun.awt.SunHints;
32import 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
44public 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
26package sun.java2d.loops;
27
28public 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
26package 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 */
39public 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
26package sun.java2d.loops;
27
28import java.awt.Composite;
29import java.lang.ref.WeakReference;
30import sun.java2d.loops.GraphicsPrimitive;
31import sun.java2d.SurfaceData;
32import 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
46public 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
26package sun.java2d.loops;
27
28import java.awt.image.BufferedImage;
29import java.awt.image.ColorModel;
30import sun.awt.image.PixelConverter;
31import 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 */
56public 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
26package sun.java2d.loops;
27
28import java.awt.Composite;
29import java.awt.geom.AffineTransform;
30import java.lang.ref.WeakReference;
31import sun.java2d.SurfaceData;
32import sun.java2d.loops.GraphicsPrimitive;
33import 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
47public 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
26package sun.java2d.loops;
27
28import java.awt.Composite;
29import java.awt.geom.AffineTransform;
30import java.lang.ref.WeakReference;
31import sun.java2d.SurfaceData;
32import sun.java2d.loops.GraphicsPrimitive;
33import 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 */
46public 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
26package sun.java2d.loops;
27
28import java.awt.image.ColorModel;
29import java.awt.Color;
30import java.awt.Composite;
31import java.awt.CompositeContext;
32import java.awt.RenderingHints;
33import sun.java2d.SurfaceData;
34import sun.java2d.SunCompositeContext;
35
36/**
37 * Bitwise XOR Composite class.
38 */
39
40public 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
3TARG=\
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
36DISBIN=$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
3DIRS=\
4 cmm\
5 loops\
6 opengl\
7 pipe\
8 pisces\
9
10TARG=\
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
32DISBIN=$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
26package sun.java2d.opengl;
27
28import java.awt.Composite;
29import java.awt.Transparency;
30import java.awt.geom.AffineTransform;
31import java.awt.image.AffineTransformOp;
32import java.awt.image.BufferedImage;
33import java.awt.image.BufferedImageOp;
34import java.lang.ref.WeakReference;
35import sun.java2d.SurfaceData;
36import sun.java2d.loops.Blit;
37import sun.java2d.loops.CompositeType;
38import sun.java2d.loops.GraphicsPrimitive;
39import sun.java2d.loops.GraphicsPrimitiveMgr;
40import sun.java2d.loops.ScaledBlit;
41import sun.java2d.loops.SurfaceType;
42import sun.java2d.loops.TransformBlit;
43import sun.java2d.pipe.Region;
44import sun.java2d.pipe.RenderBuffer;
45import sun.java2d.pipe.RenderQueue;
46import static sun.java2d.pipe.BufferedOpCodes.*;
47
48class 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
362class 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
384class 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
409class 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
432class 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
454class 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
479class 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
501class 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
546class 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
570class 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
597class 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
621class 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
645class 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
667class 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
692class 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 */
721class 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
26package sun.java2d.opengl;
27
28import java.awt.image.AffineTransformOp;
29import java.awt.image.BufferedImage;
30import java.awt.image.BufferedImageOp;
31import java.awt.image.ConvolveOp;
32import java.awt.image.LookupOp;
33import java.awt.image.RescaleOp;
34import sun.java2d.SunGraphics2D;
35import sun.java2d.SurfaceData;
36import sun.java2d.loops.CompositeType;
37import sun.java2d.pipe.BufferedBufImgOps;
38import static sun.java2d.opengl.OGLContext.OGLContextCaps.*;
39
40class 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
26package sun.java2d.opengl;
27
28import sun.java2d.pipe.BufferedContext;
29import sun.java2d.pipe.RenderBuffer;
30import sun.java2d.pipe.RenderQueue;
31import sun.java2d.pipe.hw.ContextCapabilities;
32import static sun.java2d.pipe.BufferedOpCodes.*;
33import 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 */
39public 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
26package sun.java2d.opengl;
27
28import java.awt.Color;
29import java.awt.Image;
30import java.awt.geom.AffineTransform;
31import java.awt.image.AffineTransformOp;
32import java.awt.image.BufferedImage;
33import java.awt.image.BufferedImageOp;
34import sun.java2d.SunGraphics2D;
35import sun.java2d.SurfaceData;
36import sun.java2d.loops.SurfaceType;
37import sun.java2d.loops.TransformBlit;
38import sun.java2d.pipe.DrawImage;
39
40public 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
26package sun.java2d.opengl;
27
28import sun.java2d.SurfaceData;
29import sun.awt.image.SurfaceManager;
30import 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 */
37interface 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
26package sun.java2d.opengl;
27
28import java.awt.Composite;
29import sun.java2d.SurfaceData;
30import sun.java2d.loops.CompositeType;
31import sun.java2d.loops.GraphicsPrimitive;
32import sun.java2d.loops.GraphicsPrimitiveMgr;
33import sun.java2d.loops.SurfaceType;
34import sun.java2d.pipe.Region;
35import sun.java2d.pipe.BufferedMaskBlit;
36import static sun.java2d.loops.CompositeType.*;
37import static sun.java2d.loops.SurfaceType.*;
38
39class 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
26package sun.java2d.opengl;
27
28import java.awt.Composite;
29import sun.java2d.SunGraphics2D;
30import sun.java2d.loops.GraphicsPrimitive;
31import sun.java2d.loops.GraphicsPrimitiveMgr;
32import sun.java2d.loops.CompositeType;
33import sun.java2d.loops.SurfaceType;
34import sun.java2d.pipe.BufferedMaskFill;
35import static sun.java2d.loops.CompositeType.*;
36import static sun.java2d.loops.SurfaceType.*;
37
38class 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
26package sun.java2d.opengl;
27
28import java.awt.GradientPaint;
29import java.awt.LinearGradientPaint;
30import java.awt.MultipleGradientPaint;
31import java.awt.MultipleGradientPaint.ColorSpaceType;
32import java.awt.MultipleGradientPaint.CycleMethod;
33import java.awt.RadialGradientPaint;
34import java.awt.TexturePaint;
35import java.awt.image.BufferedImage;
36import java.util.HashMap;
37import java.util.Map;
38import sun.java2d.SunGraphics2D;
39import sun.java2d.SurfaceData;
40import sun.java2d.loops.CompositeType;
41import static sun.java2d.pipe.BufferedPaints.*;
42import static sun.java2d.opengl.OGLContext.OGLContextCaps.*;
43
44abstract 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
26package sun.java2d.opengl;
27
28import sun.java2d.pipe.RenderBuffer;
29import sun.java2d.pipe.RenderQueue;
30import 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 */
38public 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
26package sun.java2d.opengl;
27
28import java.awt.Transparency;
29import java.awt.geom.Path2D;
30import sun.java2d.SunGraphics2D;
31import sun.java2d.loops.GraphicsPrimitive;
32import sun.java2d.pipe.BufferedRenderPipe;
33import sun.java2d.pipe.ParallelogramPipe;
34import sun.java2d.pipe.RenderQueue;
35import sun.java2d.pipe.SpanIterator;
36import static sun.java2d.pipe.BufferedOpCodes.*;
37
38class 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
26package sun.java2d.opengl;
27
28import java.awt.AlphaComposite;
29import java.awt.GraphicsEnvironment;
30import java.awt.Rectangle;
31import java.awt.Transparency;
32import java.awt.image.ColorModel;
33import java.awt.image.Raster;
34import sun.awt.SunHints;
35import sun.awt.image.PixelConverter;
36import sun.java2d.pipe.hw.AccelSurface;
37import sun.java2d.SunGraphics2D;
38import sun.java2d.SurfaceData;
39import sun.java2d.SurfaceDataProxy;
40import sun.java2d.loops.CompositeType;
41import sun.java2d.loops.GraphicsPrimitive;
42import sun.java2d.loops.MaskFill;
43import sun.java2d.loops.SurfaceType;
44import sun.java2d.pipe.ParallelogramPipe;
45import sun.java2d.pipe.PixelToParallelogramConverter;
46import sun.java2d.pipe.RenderBuffer;
47import sun.java2d.pipe.TextPipe;
48import static sun.java2d.pipe.BufferedOpCodes.*;
49import 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 */
98public 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.