1. /*
  2. * @(#)ImagePainter.java 1.5 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.java.swing.plaf.gtk;
  8. import java.awt.*;
  9. import javax.swing.*;
  10. /**
  11. * ImagePainter fills in the specified region using an Image. The Image
  12. * is split into 9 segments: north, north east, east, south east, south,
  13. * south west, west, north west and the center. The corners are defined
  14. * by way of an insets, and the remaining regions are either tiled or
  15. * scaled to fit.
  16. *
  17. * @version 1.5, 01/23/03
  18. * @author Scott Violet
  19. */
  20. class ImagePainter extends SynthPainter {
  21. private Image image;
  22. private Insets sInsets;
  23. private Insets dInsets;
  24. private String path;
  25. private boolean tiles;
  26. private boolean paintCenter;
  27. private Object renderingHint;
  28. ImagePainter(boolean tiles, boolean paintCenter, Object renderingHint,
  29. Insets sourceInsets, Insets destinationInsets) {
  30. this.sInsets = (Insets)sourceInsets.clone();
  31. if (destinationInsets == null) {
  32. dInsets = sInsets;
  33. }
  34. else {
  35. this.dInsets = (Insets)destinationInsets.clone();
  36. }
  37. this.tiles = tiles;
  38. this.paintCenter = paintCenter;
  39. this.renderingHint = renderingHint;
  40. }
  41. public ImagePainter(boolean tiles, boolean paintCenter,
  42. Object renderingHint, Insets sourceInsets,
  43. Insets destinationInsets, Image image) {
  44. this(tiles, paintCenter, renderingHint, sourceInsets,
  45. destinationInsets);
  46. this.image = image;
  47. }
  48. public ImagePainter(boolean tiles, boolean paintCenter,
  49. Object renderingHint, Insets sourceInsets,
  50. Insets destinationInsets, String path) {
  51. this(tiles, paintCenter, renderingHint, sourceInsets,
  52. destinationInsets);
  53. this.path = path;
  54. }
  55. public boolean getTiles() {
  56. return tiles;
  57. }
  58. public boolean getPaintsCenter() {
  59. return paintCenter;
  60. }
  61. public Object getRenderingHint() {
  62. return renderingHint;
  63. }
  64. public Insets getInsets(Insets insets) {
  65. if (insets == null) {
  66. return (Insets)this.dInsets.clone();
  67. }
  68. insets.left = this.dInsets.left;
  69. insets.right = this.dInsets.right;
  70. insets.top = this.dInsets.top;
  71. insets.bottom = this.dInsets.bottom;
  72. return insets;
  73. }
  74. public Image getImage() {
  75. if (image == null) {
  76. image = new ImageIcon(path).getImage();
  77. }
  78. return image;
  79. }
  80. public void paint(SynthContext state, Object paintKey,
  81. Graphics g, int x, int y, int w, int h) {
  82. Image image;
  83. Object lastHint;
  84. Object renderingHint = getRenderingHint();
  85. if (renderingHint != null) {
  86. Graphics2D g2 = (Graphics2D)g;
  87. lastHint = g2.getRenderingHint(RenderingHints.KEY_INTERPOLATION);
  88. if (lastHint == null) {
  89. lastHint = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
  90. }
  91. g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
  92. renderingHint);
  93. }
  94. else {
  95. lastHint = null;
  96. }
  97. if ((image = getImage()) != null) {
  98. Insets sInsets = this.sInsets;
  99. Insets dInsets = this.dInsets;
  100. int iw = image.getWidth(null);
  101. int ih = image.getHeight(null);
  102. boolean stretch = !getTiles();
  103. // top left
  104. g.drawImage(image, x, y, x + dInsets.left, y + dInsets.top,
  105. 0, 0, sInsets.left, sInsets.right, null);
  106. // top
  107. drawChunk(image, g, stretch, x + dInsets.left, y,
  108. x + w - dInsets.right, y + dInsets.top, sInsets.left, 0,
  109. iw - sInsets.right, sInsets.top, true);
  110. // top right
  111. g.drawImage(image, x + w - dInsets.right, y, x + w,
  112. y + dInsets.top, iw - sInsets.right, 0, iw,
  113. sInsets.top, null);
  114. // right
  115. drawChunk(image, g, stretch, x + w - dInsets.right,
  116. y + dInsets.top, x + w, y + h - dInsets.bottom,
  117. iw - sInsets.right, sInsets.top, iw,
  118. ih - sInsets.bottom, false);
  119. // bottom right
  120. g.drawImage(image, x + w - dInsets.right,
  121. y + h - dInsets.bottom, x + w, y + h,
  122. iw - sInsets.right, ih - sInsets.bottom, iw, ih,
  123. null);
  124. // bottom
  125. drawChunk(image, g, stretch, x + dInsets.left,
  126. y + h - dInsets.bottom, x + w - dInsets.right,
  127. y + h, sInsets.left, ih - sInsets.bottom,
  128. iw - sInsets.right, ih, true);
  129. // bottom left
  130. g.drawImage(image, x, y + h - dInsets.bottom, x + dInsets.left,
  131. y + h, 0, ih - sInsets.bottom, sInsets.left, ih,
  132. null);
  133. // left
  134. drawChunk(image, g, stretch, x, y + dInsets.top,
  135. x + dInsets.left, y + h - dInsets.bottom,
  136. 0, sInsets.top, sInsets.left, ih - sInsets.bottom,
  137. false);
  138. // center
  139. if (getPaintsCenter()) {
  140. g.drawImage(image, x + dInsets.left, y + dInsets.top,
  141. x + w - dInsets.right, y + h - dInsets.bottom,
  142. sInsets.left, sInsets.top, iw - sInsets.right,
  143. ih - sInsets.bottom, null);
  144. }
  145. }
  146. if (renderingHint != null) {
  147. ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_INTERPOLATION,
  148. lastHint);
  149. }
  150. }
  151. private void drawChunk(Image image, Graphics g, boolean stretch,
  152. int dx1, int dy1, int dx2, int dy2, int sx1,
  153. int sy1, int sx2, int sy2,
  154. boolean xDirection) {
  155. if (stretch) {
  156. g.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null);
  157. }
  158. else {
  159. int xSize = sx2 - sx1;
  160. int ySize = sy2 - sy1;
  161. int deltaX;
  162. int deltaY;
  163. if (xDirection) {
  164. deltaX = xSize;
  165. deltaY = 0;
  166. }
  167. else {
  168. deltaX = 0;
  169. deltaY = ySize;
  170. }
  171. while (dx1 < dx2 && dy1 < dy2) {
  172. int newDX2 = Math.min(dx2, dx1 + xSize);
  173. int newDY2 = Math.min(dy2, dy1 + ySize);
  174. g.drawImage(image, dx1, dy1, newDX2, newDY2,
  175. sx1, sy1, sx1 + newDX2 - dx1,
  176. sy1 + newDY2 - dy1, null);
  177. dx1 += deltaX;
  178. dy1 += deltaY;
  179. }
  180. }
  181. }
  182. }