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

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