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.

PSPainterTestCase.java 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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. package org.apache.fop.render.ps;
  18. import java.awt.Color;
  19. import java.awt.Rectangle;
  20. import java.io.ByteArrayOutputStream;
  21. import java.io.File;
  22. import java.io.IOException;
  23. import java.util.Collections;
  24. import java.util.HashMap;
  25. import java.util.Map;
  26. import javax.xml.transform.stream.StreamResult;
  27. import org.junit.Assert;
  28. import org.junit.Before;
  29. import org.junit.Test;
  30. import org.mockito.verification.VerificationMode;
  31. import static org.junit.Assert.fail;
  32. import static org.mockito.Matchers.any;
  33. import static org.mockito.Matchers.anyFloat;
  34. import static org.mockito.Matchers.anyInt;
  35. import static org.mockito.Mockito.mock;
  36. import static org.mockito.Mockito.never;
  37. import static org.mockito.Mockito.times;
  38. import static org.mockito.Mockito.verify;
  39. import static org.mockito.Mockito.when;
  40. import org.apache.xmlgraphics.ps.PSGenerator;
  41. import org.apache.xmlgraphics.ps.dsc.ResourceTracker;
  42. import org.apache.fop.apps.FOUserAgent;
  43. import org.apache.fop.apps.FopFactory;
  44. import org.apache.fop.fo.Constants;
  45. import org.apache.fop.fonts.EmbeddingMode;
  46. import org.apache.fop.fonts.Font;
  47. import org.apache.fop.fonts.FontInfo;
  48. import org.apache.fop.fonts.FontTriplet;
  49. import org.apache.fop.fonts.MultiByteFont;
  50. import org.apache.fop.fonts.Typeface;
  51. import org.apache.fop.render.intermediate.IFContext;
  52. import org.apache.fop.render.intermediate.IFException;
  53. import org.apache.fop.render.intermediate.IFState;
  54. import org.apache.fop.traits.BorderProps;
  55. public class PSPainterTestCase {
  56. private PSDocumentHandler docHandler;
  57. private PSPainter psPainter;
  58. private PSGenerator gen;
  59. private IFState state;
  60. @Before
  61. public void setup() {
  62. state = IFState.create();
  63. FOUserAgent userAgent = mock(FOUserAgent.class);
  64. when(userAgent.getRendererOptions()).thenReturn(Collections.EMPTY_MAP);
  65. IFContext context = mock(IFContext.class);
  66. when(context.getUserAgent()).thenReturn(userAgent);
  67. docHandler = new PSDocumentHandler(context);
  68. gen = mock(PSGenerator.class);
  69. docHandler.gen = gen;
  70. state = IFState.create();
  71. psPainter = new PSPainter(docHandler, state);
  72. }
  73. @Test
  74. public void testNonZeroFontSize() throws IOException {
  75. testFontSize(6, times(1));
  76. }
  77. @Test
  78. public void testZeroFontSize() throws IOException {
  79. testFontSize(0, never());
  80. }
  81. private void testFontSize(int fontSize, VerificationMode test) throws IOException {
  82. state.setFontSize(fontSize);
  83. try {
  84. psPainter.drawText(10, 10, 2, 2, null, "Test");
  85. } catch (Exception ex) {
  86. //Expected
  87. }
  88. verify(gen, test).useColor(state.getTextColor());
  89. }
  90. @Test
  91. public void testDrawBorderRect() {
  92. // the goal of this test is to check that the drawing of rounded corners in PS calls
  93. // PSGraphicsPaiter.cubicBezierTo(); the check is done by verifying that a curveto command is written
  94. // to the PSGenerator
  95. PSGenerator psGenerator = mock(PSGenerator.class);
  96. when(psGenerator.formatDouble(anyFloat())).thenReturn("20.0"); // simplify!
  97. PSRenderingUtil psRenderingUtil = mock(PSRenderingUtil.class);
  98. PSDocumentHandler psDocumentHandler = mock(PSDocumentHandler.class);
  99. when(psDocumentHandler.getGenerator()).thenReturn(psGenerator);
  100. when(psDocumentHandler.getPSUtil()).thenReturn(psRenderingUtil);
  101. PSPainter psPainter = new PSPainter(psDocumentHandler);
  102. // build rectangle 200 x 50 (points, which are converted to milipoints)
  103. Rectangle rectangle = new Rectangle(0, 0, 200000, 50000);
  104. // build border properties: width 4pt, radius 30pt
  105. BorderProps border = new BorderProps(Constants.EN_SOLID, 4000, 30000, 30000, Color.BLACK,
  106. BorderProps.Mode.SEPARATE);
  107. try {
  108. psPainter.drawBorderRect(rectangle, border, border, border, border, Color.WHITE);
  109. verify(psGenerator, times(16)).writeln("20.0 20.0 20.0 20.0 20.0 20.0 curveto ");
  110. } catch (Exception e) {
  111. fail("something broke...");
  112. }
  113. }
  114. @Test
  115. public void testDrawText() {
  116. int fontSize = 12000;
  117. String fontName = "MockFont";
  118. PSGenerator psGenerator = mock(PSGenerator.class);
  119. PSRenderingUtil psRenderingUtil = mock(PSRenderingUtil.class);
  120. PSDocumentHandler psDocumentHandler = mock(PSDocumentHandler.class);
  121. FontInfo fontInfo = mock(FontInfo.class);
  122. PSFontResource psFontResource = mock(PSFontResource.class);
  123. MultiByteFont multiByteFont = mock(MultiByteFont.class);
  124. Font font = mock(Font.class);
  125. when(psDocumentHandler.getGenerator()).thenReturn(psGenerator);
  126. when(psDocumentHandler.getPSUtil()).thenReturn(psRenderingUtil);
  127. when(psDocumentHandler.getFontInfo()).thenReturn(fontInfo);
  128. when(psDocumentHandler.getPSResourceForFontKey(fontName)).thenReturn(psFontResource);
  129. when(fontInfo.getInternalFontKey(any(FontTriplet.class))).thenReturn(fontName);
  130. when(fontInfo.getFontInstance(any(FontTriplet.class), anyInt())).thenReturn(font);
  131. Map<String, Typeface> fonts = new HashMap<String, Typeface>();
  132. fonts.put(fontName, multiByteFont);
  133. when(fontInfo.getFonts()).thenReturn(fonts);
  134. IFState ifState = IFState.create();
  135. ifState.setFontSize(fontSize);
  136. PSPainter psPainter = new PSPainter(psDocumentHandler, ifState);
  137. int x = 100000;
  138. int y = 100000;
  139. int letterSpacing = 0;
  140. int wordSpacing = 0;
  141. int[][] dp = {{100, 100, 0, 0}, null, null, {200, 200, -100, -100}};
  142. double xAsDouble = (x + dp[0][0]) / 1000.0;
  143. double yAsDouble = (y - dp[0][1]) / 1000.0;
  144. when(psGenerator.formatDouble(xAsDouble)).thenReturn("100.100");
  145. when(psGenerator.formatDouble(yAsDouble)).thenReturn("99.900");
  146. String text = "Hello Mock!";
  147. try {
  148. psPainter.drawText(x, y, letterSpacing, wordSpacing, dp, text);
  149. verify(psGenerator).writeln("1 0 0 -1 100.100 99.900 Tm");
  150. verify(psGenerator).writeln("[<0000> [-100 100] <00000000> [200 -200] <0000> [-300 300] "
  151. + "<0000000000000000000000000000>] TJ");
  152. } catch (Exception e) {
  153. fail("something broke...");
  154. }
  155. }
  156. @Test
  157. public void testOTF() throws IFException, IOException {
  158. FOUserAgent ua = FopFactory.newInstance(new File(".").toURI()).newFOUserAgent();
  159. final IFState state = IFState.create();
  160. PSDocumentHandler dh = new PSDocumentHandler(new IFContext(ua)) {
  161. protected PSFontResource getPSResourceForFontKey(String key) {
  162. return new PSFontResource() {
  163. String getName() {
  164. return state.getFontFamily();
  165. }
  166. void notifyResourceUsageOnPage(ResourceTracker resourceTracker) {
  167. }
  168. };
  169. }
  170. };
  171. FontInfo fi = new FontInfo();
  172. addFont(fi, "OTFFont", true);
  173. addFont(fi, "TTFFont", false);
  174. dh.setFontInfo(fi);
  175. ByteArrayOutputStream bos = new ByteArrayOutputStream();
  176. dh.setResult(new StreamResult(bos));
  177. dh.startDocument();
  178. state.setFontSize(10);
  179. state.setTextColor(Color.BLACK);
  180. state.setFontStyle("");
  181. PSPainter p = new PSPainter(dh, state) {
  182. protected String getFontKey(FontTriplet triplet) throws IFException {
  183. return state.getFontFamily();
  184. }
  185. };
  186. state.setFontFamily("TTFFont");
  187. p.drawText(0, 0, 0, 0, null, "test1");
  188. state.setFontFamily("OTFFont");
  189. p.drawText(0, 0, 0, 0, null, "test2");
  190. p.drawText(0, 0, 0, 0, null, "test3");
  191. state.setFontFamily("TTFFont");
  192. p.drawText(0, 0, 0, 0, null, "test4");
  193. Assert.assertTrue(bos.toString(), bos.toString().endsWith("BT\n"
  194. + "/TTFFont 0.01 F\n"
  195. + "1 0 0 -1 0 0 Tm\n"
  196. + "<00000000000000000000> t\n"
  197. + "/OTFFont.0 0.01 F\n"
  198. + "1 0 0 -1 0 0 Tm\n"
  199. + "<0000000000> t\n"
  200. + "1 0 0 -1 0 0 Tm\n"
  201. + "<0000000000> t\n"
  202. + "/TTFFont 0.01 F\n"
  203. + "1 0 0 -1 0 0 Tm\n"
  204. + "<00000000000000000000> t\n"));
  205. }
  206. private void addFont(FontInfo fi, String name, boolean otf) {
  207. fi.addFontProperties(name, name, "", 0);
  208. MultiByteFont mbf = new MultiByteFont(null, EmbeddingMode.AUTO);
  209. mbf.setWidthArray(new int[100]);
  210. mbf.setIsOTFFile(otf);
  211. fi.addMetrics(name, mbf);
  212. }
  213. }