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.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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. Integer bytesAvailable = dataStream.getCurrentPage().getPresentationTextObject().getBytesAvailable();
  39. if (bytesAvailable != null && bytesAvailable < 1024) {
  40. dataStream.getCurrentPage().endPresentationObject();
  41. }
  42. BorderPaintingInfo borderPaintInfo = (BorderPaintingInfo)paintInfo;
  43. float w = borderPaintInfo.getX2() - borderPaintInfo.getX1();
  44. float h = borderPaintInfo.getY2() - borderPaintInfo.getY1();
  45. if ((w < 0) || (h < 0)) {
  46. log.error("Negative extent received. Border won't be painted.");
  47. return;
  48. }
  49. int pageWidth = dataStream.getCurrentPage().getWidth();
  50. int pageHeight = dataStream.getCurrentPage().getHeight();
  51. AFPUnitConverter unitConv = paintingState.getUnitConverter();
  52. AffineTransform at = paintingState.getData().getTransform();
  53. float x1 = unitConv.pt2units(borderPaintInfo.getX1());
  54. float y1 = unitConv.pt2units(borderPaintInfo.getY1());
  55. float x2 = unitConv.pt2units(borderPaintInfo.getX2());
  56. float y2 = unitConv.pt2units(borderPaintInfo.getY2());
  57. switch (paintingState.getRotation()) {
  58. case 90:
  59. x1 += at.getTranslateY();
  60. y1 += (float) (pageWidth - at.getTranslateX());
  61. x2 += at.getTranslateY();
  62. y2 += (float) (pageWidth - at.getTranslateX());
  63. break;
  64. case 180:
  65. x1 += (float) (pageWidth - at.getTranslateX());
  66. y1 += (float) (pageHeight - at.getTranslateY());
  67. x2 += (float) (pageWidth - at.getTranslateX());
  68. y2 += (float) (pageHeight - at.getTranslateY());
  69. break;
  70. case 270:
  71. x1 = (float) (pageHeight - at.getTranslateY());
  72. y1 += (float) at.getTranslateX();
  73. x2 += x1;
  74. y2 += (float) at.getTranslateX();
  75. break;
  76. case 0:
  77. default:
  78. x1 += at.getTranslateX();
  79. y1 += at.getTranslateY();
  80. x2 += at.getTranslateX();
  81. y2 += at.getTranslateY();
  82. break;
  83. }
  84. AFPLineDataInfo lineDataInfo = new AFPLineDataInfo();
  85. lineDataInfo.setColor(borderPaintInfo.getColor());
  86. lineDataInfo.setRotation(paintingState.getRotation());
  87. lineDataInfo.setX1(Math.round(x1));
  88. lineDataInfo.setY1(Math.round(y1));
  89. float thickness;
  90. if (borderPaintInfo.isHorizontal()) {
  91. thickness = y2 - y1;
  92. } else {
  93. thickness = x2 - x1;
  94. }
  95. lineDataInfo.setThickness(Math.round(thickness));
  96. // handle border-*-style
  97. switch (borderPaintInfo.getStyle()) {
  98. case Constants.EN_DOUBLE:
  99. int thickness3 = (int)Math.floor(thickness / 3f);
  100. lineDataInfo.setThickness(thickness3);
  101. if (borderPaintInfo.isHorizontal()) {
  102. lineDataInfo.setX2(Math.round(x2));
  103. lineDataInfo.setY2(lineDataInfo.getY1());
  104. dataStream.createLine(lineDataInfo);
  105. int distance = thickness3 * 2;
  106. lineDataInfo = new AFPLineDataInfo(lineDataInfo);
  107. lineDataInfo.setY1(lineDataInfo.getY1() + distance);
  108. lineDataInfo.setY2(lineDataInfo.getY2() + distance);
  109. dataStream.createLine(lineDataInfo);
  110. } else {
  111. lineDataInfo.setX2(lineDataInfo.getX1());
  112. lineDataInfo.setY2(Math.round(y2));
  113. dataStream.createLine(lineDataInfo);
  114. int distance = thickness3 * 2;
  115. lineDataInfo = new AFPLineDataInfo(lineDataInfo);
  116. lineDataInfo.setX1(lineDataInfo.getX1() + distance);
  117. lineDataInfo.setX2(lineDataInfo.getX2() + distance);
  118. dataStream.createLine(lineDataInfo);
  119. }
  120. break;
  121. case Constants.EN_DASHED:
  122. if (borderPaintInfo.isHorizontal()) {
  123. int dashWidth = (int) unitConv.pt2units(BorderPainter.dashWidthCalculator(w, h));
  124. lineDataInfo.setX2(lineDataInfo.getX1() + dashWidth);
  125. lineDataInfo.setY2(lineDataInfo.getY1());
  126. int ex2 = Math.round(x2);
  127. int spaceWidth = (int) (BorderPainter.DASHED_BORDER_SPACE_RATIO * dashWidth);
  128. while (lineDataInfo.getX2() <= ex2 && dashWidth > 0) {
  129. dataStream.createLine(lineDataInfo);
  130. lineDataInfo.setX1(lineDataInfo.getX2() + spaceWidth);
  131. lineDataInfo.setX2(lineDataInfo.getX1() + dashWidth);
  132. }
  133. } else {
  134. int dashWidth = (int) unitConv.pt2units(BorderPainter.dashWidthCalculator(h, w));
  135. lineDataInfo.setX2(lineDataInfo.getX1());
  136. lineDataInfo.setY2(lineDataInfo.getY1() + dashWidth);
  137. int ey2 = Math.round(y2);
  138. int spaceWidth = (int) (BorderPainter.DASHED_BORDER_SPACE_RATIO * dashWidth);
  139. while (lineDataInfo.getY2() <= ey2 && dashWidth > 0) {
  140. dataStream.createLine(lineDataInfo);
  141. lineDataInfo.setY1(lineDataInfo.getY2() + spaceWidth);
  142. lineDataInfo.setY2(lineDataInfo.getY1() + dashWidth);
  143. }
  144. }
  145. break;
  146. case Constants.EN_DOTTED:
  147. if (borderPaintInfo.isHorizontal()) {
  148. lineDataInfo.setX2(lineDataInfo.getX1() + lineDataInfo.getThickness());
  149. lineDataInfo.setY2(lineDataInfo.getY1());
  150. int ex2 = Math.round(x2);
  151. while (lineDataInfo.getX1() + lineDataInfo.getThickness() < ex2) {
  152. dataStream.createLine(lineDataInfo);
  153. lineDataInfo.setX1(lineDataInfo.getX1() + 3 * lineDataInfo.getThickness());
  154. lineDataInfo.setX2(lineDataInfo.getX1() + lineDataInfo.getThickness());
  155. }
  156. } else {
  157. lineDataInfo.setX2(lineDataInfo.getX1());
  158. lineDataInfo.setY2(lineDataInfo.getY1() + lineDataInfo.getThickness());
  159. int ey2 = Math.round(y2);
  160. while (lineDataInfo.getY1() + lineDataInfo.getThickness() < ey2) {
  161. dataStream.createLine(lineDataInfo);
  162. lineDataInfo.setY1(lineDataInfo.getY1() + 3 * lineDataInfo.getThickness());
  163. lineDataInfo.setY2(lineDataInfo.getY1() + lineDataInfo.getThickness());
  164. }
  165. }
  166. break;
  167. case Constants.EN_GROOVE:
  168. case Constants.EN_RIDGE:
  169. //TODO
  170. int yNew;
  171. lineDataInfo.setX2(Math.round(x2));
  172. float colFactor = (borderPaintInfo.getStyle() == Constants.EN_GROOVE ? 0.4f : -0.4f);
  173. float h3 = (y2 - y1) / 3;
  174. lineDataInfo.setColor(
  175. ColorUtil.lightenColor(borderPaintInfo.getColor(), -colFactor));
  176. lineDataInfo.setThickness(Math.round(h3));
  177. yNew = Math.round(y1);
  178. lineDataInfo.setY1(yNew);
  179. lineDataInfo.setY2(yNew);
  180. dataStream.createLine(lineDataInfo);
  181. lineDataInfo.setColor(borderPaintInfo.getColor());
  182. yNew = Math.round(y1 + h3);
  183. lineDataInfo.setY1(yNew);
  184. lineDataInfo.setY2(yNew);
  185. dataStream.createLine(lineDataInfo);
  186. lineDataInfo.setColor(ColorUtil.lightenColor(borderPaintInfo.getColor(), colFactor));
  187. yNew = Math.round(y1 + h3 + h3);
  188. lineDataInfo.setY1(yNew);
  189. lineDataInfo.setY2(yNew);
  190. dataStream.createLine(lineDataInfo);
  191. break;
  192. case Constants.EN_HIDDEN:
  193. break;
  194. case Constants.EN_INSET:
  195. case Constants.EN_OUTSET:
  196. case Constants.EN_SOLID:
  197. default:
  198. if (borderPaintInfo.isHorizontal()) {
  199. lineDataInfo.setX2(Math.round(x2));
  200. lineDataInfo.setY2(lineDataInfo.getY1());
  201. } else {
  202. lineDataInfo.setX2(lineDataInfo.getX1());
  203. lineDataInfo.setY2(Math.round(y2));
  204. }
  205. dataStream.createLine(lineDataInfo);
  206. }
  207. }
  208. }