You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AFPBorderPainter.java 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.afp;
  19. import java.awt.geom.AffineTransform;
  20. import org.apache.fop.fo.Constants;
  21. import org.apache.fop.render.intermediate.BorderPainter;
  22. import org.apache.fop.util.ColorUtil;
  23. /**
  24. * Handles the drawing of borders/lines in AFP
  25. */
  26. public class AFPBorderPainter extends AbstractAFPPainter {
  27. /**
  28. * Main constructor
  29. *
  30. * @param paintingState the AFP painting state converter
  31. * @param dataStream the AFP datastream
  32. */
  33. public AFPBorderPainter(AFPPaintingState paintingState, DataStream dataStream) {
  34. super(paintingState, dataStream);
  35. }
  36. /** {@inheritDoc} */
  37. public void paint(PaintingInfo paintInfo) {
  38. BorderPaintingInfo borderPaintInfo = (BorderPaintingInfo)paintInfo;
  39. float w = borderPaintInfo.getX2() - borderPaintInfo.getX1();
  40. float h = borderPaintInfo.getY2() - borderPaintInfo.getY1();
  41. if ((w < 0) || (h < 0)) {
  42. log.error("Negative extent received. Border won't be painted.");
  43. return;
  44. }
  45. int pageWidth = dataStream.getCurrentPage().getWidth();
  46. int pageHeight = dataStream.getCurrentPage().getHeight();
  47. AFPUnitConverter unitConv = paintingState.getUnitConverter();
  48. AffineTransform at = paintingState.getData().getTransform();
  49. float x1 = unitConv.pt2units(borderPaintInfo.getX1());
  50. float y1 = unitConv.pt2units(borderPaintInfo.getY1());
  51. float x2 = unitConv.pt2units(borderPaintInfo.getX2());
  52. float y2 = unitConv.pt2units(borderPaintInfo.getY2());
  53. switch (paintingState.getRotation()) {
  54. case 90:
  55. x1 += at.getTranslateY();
  56. y1 += (float) (pageWidth - at.getTranslateX());
  57. x2 += at.getTranslateY();
  58. y2 += (float) (pageWidth - at.getTranslateX());
  59. break;
  60. case 180:
  61. x1 += (float) (pageWidth - at.getTranslateX());
  62. y1 += (float) (pageHeight - at.getTranslateY());
  63. x2 += (float) (pageWidth - at.getTranslateX());
  64. y2 += (float) (pageHeight - at.getTranslateY());
  65. break;
  66. case 270:
  67. x1 = (float) (pageHeight - at.getTranslateY());
  68. y1 += (float) at.getTranslateX();
  69. x2 += x1;
  70. y2 += (float) at.getTranslateX();
  71. break;
  72. case 0:
  73. default:
  74. x1 += at.getTranslateX();
  75. y1 += at.getTranslateY();
  76. x2 += at.getTranslateX();
  77. y2 += at.getTranslateY();
  78. break;
  79. }
  80. AFPLineDataInfo lineDataInfo = new AFPLineDataInfo();
  81. lineDataInfo.setColor(borderPaintInfo.getColor());
  82. lineDataInfo.setRotation(paintingState.getRotation());
  83. lineDataInfo.setX1(Math.round(x1));
  84. lineDataInfo.setY1(Math.round(y1));
  85. float thickness;
  86. if (borderPaintInfo.isHorizontal()) {
  87. thickness = y2 - y1;
  88. } else {
  89. thickness = x2 - x1;
  90. }
  91. lineDataInfo.setThickness(Math.round(thickness));
  92. // handle border-*-style
  93. switch (borderPaintInfo.getStyle()) {
  94. case Constants.EN_DOUBLE:
  95. int thickness3 = (int)Math.floor(thickness / 3f);
  96. lineDataInfo.setThickness(thickness3);
  97. if (borderPaintInfo.isHorizontal()) {
  98. lineDataInfo.setX2(Math.round(x2));
  99. lineDataInfo.setY2(lineDataInfo.getY1());
  100. dataStream.createLine(lineDataInfo);
  101. int distance = thickness3 * 2;
  102. lineDataInfo = new AFPLineDataInfo(lineDataInfo);
  103. lineDataInfo.setY1(lineDataInfo.getY1() + distance);
  104. lineDataInfo.setY2(lineDataInfo.getY2() + distance);
  105. dataStream.createLine(lineDataInfo);
  106. } else {
  107. lineDataInfo.setX2(lineDataInfo.getX1());
  108. lineDataInfo.setY2(Math.round(y2));
  109. dataStream.createLine(lineDataInfo);
  110. int distance = thickness3 * 2;
  111. lineDataInfo = new AFPLineDataInfo(lineDataInfo);
  112. lineDataInfo.setX1(lineDataInfo.getX1() + distance);
  113. lineDataInfo.setX2(lineDataInfo.getX2() + distance);
  114. dataStream.createLine(lineDataInfo);
  115. }
  116. break;
  117. case Constants.EN_DASHED:
  118. if (borderPaintInfo.isHorizontal()) {
  119. int dashWidth = (int) unitConv.pt2units(BorderPainter.dashWidthCalculator(w, h));
  120. lineDataInfo.setX2(lineDataInfo.getX1() + dashWidth);
  121. lineDataInfo.setY2(lineDataInfo.getY1());
  122. int ex2 = Math.round(x2);
  123. int spaceWidth = (int) (BorderPainter.DASHED_BORDER_SPACE_RATIO * dashWidth);
  124. while (lineDataInfo.getX2() <= ex2) {
  125. dataStream.createLine(lineDataInfo);
  126. lineDataInfo.setX1(lineDataInfo.getX2() + spaceWidth);
  127. lineDataInfo.setX2(lineDataInfo.getX1() + dashWidth);
  128. }
  129. } else {
  130. int dashWidth = (int) unitConv.pt2units(BorderPainter.dashWidthCalculator(h, w));
  131. lineDataInfo.setX2(lineDataInfo.getX1());
  132. lineDataInfo.setY2(lineDataInfo.getY1() + dashWidth);
  133. int ey2 = Math.round(y2);
  134. int spaceWidth = (int) (BorderPainter.DASHED_BORDER_SPACE_RATIO * dashWidth);
  135. while (lineDataInfo.getY2() <= ey2) {
  136. dataStream.createLine(lineDataInfo);
  137. lineDataInfo.setY1(lineDataInfo.getY2() + spaceWidth);
  138. lineDataInfo.setY2(lineDataInfo.getY1() + dashWidth);
  139. }
  140. }
  141. break;
  142. case Constants.EN_DOTTED:
  143. if (borderPaintInfo.isHorizontal()) {
  144. lineDataInfo.setX2(lineDataInfo.getX1() + lineDataInfo.getThickness());
  145. lineDataInfo.setY2(lineDataInfo.getY1());
  146. int ex2 = Math.round(x2);
  147. while (lineDataInfo.getX1() + lineDataInfo.getThickness() < ex2) {
  148. dataStream.createLine(lineDataInfo);
  149. lineDataInfo.setX1(lineDataInfo.getX1() + 3 * lineDataInfo.getThickness());
  150. lineDataInfo.setX2(lineDataInfo.getX1() + lineDataInfo.getThickness());
  151. }
  152. } else {
  153. lineDataInfo.setX2(lineDataInfo.getX1());
  154. lineDataInfo.setY2(lineDataInfo.getY1() + lineDataInfo.getThickness());
  155. int ey2 = Math.round(y2);
  156. while (lineDataInfo.getY1() + lineDataInfo.getThickness() < ey2) {
  157. dataStream.createLine(lineDataInfo);
  158. lineDataInfo.setY1(lineDataInfo.getY1() + 3 * lineDataInfo.getThickness());
  159. lineDataInfo.setY2(lineDataInfo.getY1() + lineDataInfo.getThickness());
  160. }
  161. }
  162. break;
  163. case Constants.EN_GROOVE:
  164. case Constants.EN_RIDGE:
  165. //TODO
  166. int yNew;
  167. lineDataInfo.setX2(Math.round(x2));
  168. float colFactor = (borderPaintInfo.getStyle() == Constants.EN_GROOVE ? 0.4f : -0.4f);
  169. float h3 = (y2 - y1) / 3;
  170. lineDataInfo.setColor(
  171. ColorUtil.lightenColor(borderPaintInfo.getColor(), -colFactor));
  172. lineDataInfo.setThickness(Math.round(h3));
  173. yNew = Math.round(y1);
  174. lineDataInfo.setY1(yNew);
  175. lineDataInfo.setY2(yNew);
  176. dataStream.createLine(lineDataInfo);
  177. lineDataInfo.setColor(borderPaintInfo.getColor());
  178. yNew = Math.round(y1 + h3);
  179. lineDataInfo.setY1(yNew);
  180. lineDataInfo.setY2(yNew);
  181. dataStream.createLine(lineDataInfo);
  182. lineDataInfo.setColor(ColorUtil.lightenColor(borderPaintInfo.getColor(), colFactor));
  183. yNew = Math.round(y1 + h3 + h3);
  184. lineDataInfo.setY1(yNew);
  185. lineDataInfo.setY2(yNew);
  186. dataStream.createLine(lineDataInfo);
  187. break;
  188. case Constants.EN_HIDDEN:
  189. break;
  190. case Constants.EN_INSET:
  191. case Constants.EN_OUTSET:
  192. case Constants.EN_SOLID:
  193. default:
  194. if (borderPaintInfo.isHorizontal()) {
  195. lineDataInfo.setX2(Math.round(x2));
  196. lineDataInfo.setY2(lineDataInfo.getY1());
  197. } else {
  198. lineDataInfo.setX2(lineDataInfo.getX1());
  199. lineDataInfo.setY2(Math.round(y2));
  200. }
  201. dataStream.createLine(lineDataInfo);
  202. }
  203. }
  204. }