Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  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.Point;
  20. import org.apache.commons.logging.Log;
  21. import org.apache.commons.logging.LogFactory;
  22. import org.apache.fop.afp.fonts.AFPPageFonts;
  23. import org.apache.fop.util.AbstractPaintingState;
  24. /**
  25. * This keeps information about the current painting state when writing to an AFP datastream.
  26. */
  27. public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState
  28. implements Cloneable {
  29. private static final long serialVersionUID = 8206711712452344473L;
  30. private static Log log = LogFactory.getLog("org.apache.xmlgraphics.afp");
  31. /** the portrait rotation */
  32. private int portraitRotation = 0;
  33. /** the landscape rotation */
  34. private int landscapeRotation = 270;
  35. /** color image support */
  36. private boolean colorImages = false;
  37. /** true if certain image formats may be embedded unchanged in their native format. */
  38. private boolean nativeImagesSupported = false;
  39. /** true if CMYK images (requires IOCA FS45 suppport on the target platform) may be generated */
  40. private boolean cmykImagesSupported;
  41. /** default value for image depth */
  42. private int bitsPerPixel = 8;
  43. /** the output resolution */
  44. private int resolution = 240; // 240 dpi
  45. /** the current page */
  46. private transient AFPPagePaintingState pagePaintingState = new AFPPagePaintingState();
  47. // /** reference orientation */
  48. // private int orientation = 0;
  49. /** a unit converter */
  50. private final transient AFPUnitConverter unitConv = new AFPUnitConverter(this);
  51. /**
  52. * Sets the rotation to be used for portrait pages, valid values are 0
  53. * (default), 90, 180, 270.
  54. *
  55. * @param rotation
  56. * The rotation in degrees.
  57. */
  58. public void setPortraitRotation(int rotation) {
  59. if (rotation == 0 || rotation == 90 || rotation == 180
  60. || rotation == 270) {
  61. portraitRotation = rotation;
  62. } else {
  63. throw new IllegalArgumentException(
  64. "The portrait rotation must be one"
  65. + " of the values 0, 90, 180, 270");
  66. }
  67. }
  68. /**
  69. * Returns the rotation to be used for portrait pages
  70. *
  71. * @return the rotation to be used for portrait pages
  72. */
  73. protected int getPortraitRotation() {
  74. return this.portraitRotation;
  75. }
  76. /**
  77. * Sets the rotation to be used for landscape pages, valid values are 0, 90,
  78. * 180, 270 (default).
  79. *
  80. * @param rotation
  81. * The rotation in degrees.
  82. */
  83. public void setLandscapeRotation(int rotation) {
  84. if (rotation == 0 || rotation == 90 || rotation == 180
  85. || rotation == 270) {
  86. landscapeRotation = rotation;
  87. } else {
  88. throw new IllegalArgumentException(
  89. "The landscape rotation must be one"
  90. + " of the values 0, 90, 180, 270");
  91. }
  92. }
  93. /**
  94. * Returns the landscape rotation
  95. *
  96. * @return the landscape rotation
  97. */
  98. protected int getLandscapeRotation() {
  99. return this.landscapeRotation;
  100. }
  101. /**
  102. * Sets the number of bits used per pixel
  103. *
  104. * @param bitsPerPixel
  105. * number of bits per pixel
  106. */
  107. public void setBitsPerPixel(int bitsPerPixel) {
  108. switch (bitsPerPixel) {
  109. case 1:
  110. case 4:
  111. case 8:
  112. this.bitsPerPixel = bitsPerPixel;
  113. break;
  114. default:
  115. log.warn("Invalid bits_per_pixel value, must be 1, 4 or 8.");
  116. this.bitsPerPixel = 8;
  117. break;
  118. }
  119. }
  120. /**
  121. * Returns the number of bits per pixel
  122. *
  123. * @return the number of bits per pixel
  124. */
  125. public int getBitsPerPixel() {
  126. return this.bitsPerPixel;
  127. }
  128. /**
  129. * Sets whether images are color or not
  130. *
  131. * @param colorImages
  132. * color image output
  133. */
  134. public void setColorImages(boolean colorImages) {
  135. this.colorImages = colorImages;
  136. }
  137. /**
  138. * Returns true if color images are to be used
  139. *
  140. * @return true if color images are to be used
  141. */
  142. public boolean isColorImages() {
  143. return this.colorImages;
  144. }
  145. /**
  146. * Sets whether images are natively supported or not in the AFP environment
  147. *
  148. * @param nativeImagesSupported true if images are natively supported in this AFP environment
  149. */
  150. public void setNativeImagesSupported(boolean nativeImagesSupported) {
  151. this.nativeImagesSupported = nativeImagesSupported;
  152. }
  153. /**
  154. * Returns true if images are supported natively in this AFP environment
  155. *
  156. * @return true if images are supported natively in this AFP environment
  157. */
  158. public boolean isNativeImagesSupported() {
  159. return this.nativeImagesSupported;
  160. }
  161. /**
  162. * Controls whether CMYK images (IOCA FS45) are enabled. By default, support is disabled
  163. * for wider compatibility. When disabled, any CMYK image is converted to the selected
  164. * color format.
  165. * @param value true to enabled CMYK images
  166. */
  167. public void setCMYKImagesSupported(boolean value) {
  168. this.cmykImagesSupported = value;
  169. }
  170. /**
  171. * Indicates whether CMYK images (IOCA FS45) are enabled.
  172. * @return true if IOCA FS45 is enabled
  173. */
  174. public boolean isCMYKImagesSupported() {
  175. return this.cmykImagesSupported;
  176. }
  177. /**
  178. * Sets the output/device resolution
  179. *
  180. * @param resolution
  181. * the output resolution (dpi)
  182. */
  183. public void setResolution(int resolution) {
  184. if (log.isDebugEnabled()) {
  185. log.debug("renderer-resolution set to: " + resolution + "dpi");
  186. }
  187. this.resolution = resolution;
  188. }
  189. /**
  190. * Returns the output/device resolution.
  191. *
  192. * @return the resolution in dpi
  193. */
  194. public int getResolution() {
  195. return this.resolution;
  196. }
  197. /** {@inheritDoc} */
  198. protected AbstractData instantiateData() {
  199. return new AFPData();
  200. }
  201. /** {@inheritDoc} */
  202. protected AbstractPaintingState instantiate() {
  203. return new AFPPaintingState();
  204. }
  205. /**
  206. * Returns the painting state of the current page
  207. *
  208. * @return the painting state of the current page
  209. */
  210. protected AFPPagePaintingState getPagePaintingState() {
  211. return this.pagePaintingState;
  212. }
  213. /**
  214. * Gets the current page fonts
  215. *
  216. * @return the current page fonts
  217. */
  218. public AFPPageFonts getPageFonts() {
  219. return pagePaintingState.getFonts();
  220. }
  221. /**
  222. * Sets the page width
  223. *
  224. * @param pageWidth the page width
  225. */
  226. public void setPageWidth(int pageWidth) {
  227. pagePaintingState.setWidth(pageWidth);
  228. }
  229. /**
  230. * Returns the page width
  231. *
  232. * @return the page width
  233. */
  234. public int getPageWidth() {
  235. return pagePaintingState.getWidth();
  236. }
  237. /**
  238. * Sets the page height
  239. *
  240. * @param pageHeight the page height
  241. */
  242. public void setPageHeight(int pageHeight) {
  243. pagePaintingState.setHeight(pageHeight);
  244. }
  245. /**
  246. * Returns the page height
  247. *
  248. * @return the page height
  249. */
  250. public int getPageHeight() {
  251. return pagePaintingState.getHeight();
  252. }
  253. /**
  254. * Returns the page rotation
  255. *
  256. * @return the page rotation
  257. */
  258. public int getPageRotation() {
  259. return pagePaintingState.getOrientation();
  260. }
  261. /**
  262. * Sets the uri of the current image
  263. *
  264. * @param uri the uri of the current image
  265. */
  266. public void setImageUri(String uri) {
  267. ((AFPData)getData()).imageUri = uri;
  268. }
  269. /**
  270. * Gets the uri of the current image
  271. *
  272. * @return the uri of the current image
  273. */
  274. public String getImageUri() {
  275. return ((AFPData)getData()).imageUri;
  276. }
  277. /**
  278. * Returns the currently derived rotation
  279. *
  280. * @return the currently derived rotation
  281. */
  282. public int getRotation() {
  283. return getData().getDerivedRotation();
  284. }
  285. /**
  286. * Returns the unit converter
  287. *
  288. * @return the unit converter
  289. */
  290. public AFPUnitConverter getUnitConverter() {
  291. return this.unitConv;
  292. }
  293. /**
  294. * Returns a point on the current page, taking the current painting state into account.
  295. *
  296. * @param x the X-coordinate
  297. * @param y the Y-coordinate
  298. * @return a point on the current page
  299. */
  300. public Point getPoint(int x, int y) {
  301. Point p = new Point();
  302. int rotation = getRotation();
  303. switch (rotation) {
  304. case 90:
  305. p.x = y;
  306. p.y = getPageWidth() - x;
  307. break;
  308. case 180:
  309. p.x = getPageWidth() - x;
  310. p.y = getPageHeight() - y;
  311. break;
  312. case 270:
  313. p.x = getPageHeight() - y;
  314. p.y = x;
  315. break;
  316. default:
  317. p.x = x;
  318. p.y = y;
  319. break;
  320. }
  321. return p;
  322. }
  323. /** {@inheritDoc} */
  324. public Object clone() {
  325. AFPPaintingState paintingState = (AFPPaintingState)super.clone();
  326. paintingState.pagePaintingState = (AFPPagePaintingState)this.pagePaintingState.clone();
  327. paintingState.portraitRotation = this.portraitRotation;
  328. paintingState.landscapeRotation = this.landscapeRotation;
  329. paintingState.bitsPerPixel = this.bitsPerPixel;
  330. paintingState.colorImages = this.colorImages;
  331. paintingState.resolution = this.resolution;
  332. return paintingState;
  333. }
  334. /** {@inheritDoc} */
  335. public String toString() {
  336. return "AFPPaintingState{" + "portraitRotation=" + portraitRotation
  337. + ", landscapeRotation=" + landscapeRotation
  338. + ", colorImages=" + colorImages
  339. + ", bitsPerPixel=" + bitsPerPixel
  340. + ", resolution=" + resolution
  341. + ", pageState=" + pagePaintingState
  342. + super.toString()
  343. + "}";
  344. }
  345. /**
  346. * Page level state data
  347. */
  348. private class AFPPagePaintingState implements Cloneable {
  349. /** page width */
  350. private int width = 0;
  351. /** page height */
  352. private int height = 0;
  353. /** page fonts */
  354. private AFPPageFonts fonts = new AFPPageFonts();
  355. /** page font count */
  356. private int fontCount = 0;
  357. /** page orientation */
  358. private int orientation = 0;
  359. /**
  360. * Returns the page width
  361. *
  362. * @return the page width
  363. */
  364. protected int getWidth() {
  365. return width;
  366. }
  367. /**
  368. * Sets the page width
  369. *
  370. * @param width the page width
  371. */
  372. protected void setWidth(int width) {
  373. this.width = width;
  374. }
  375. /**
  376. * Returns the page height
  377. *
  378. * @return the page height
  379. */
  380. protected int getHeight() {
  381. return height;
  382. }
  383. /**
  384. * Sets the page height
  385. *
  386. * @param height the page height
  387. */
  388. protected void setHeight(int height) {
  389. this.height = height;
  390. }
  391. /**
  392. * Returns the page fonts
  393. *
  394. * @return the page fonts
  395. */
  396. protected AFPPageFonts getFonts() {
  397. return fonts;
  398. }
  399. /**
  400. * Sets the current page fonts
  401. *
  402. * @param fonts the current page fonts
  403. */
  404. protected void setFonts(AFPPageFonts fonts) {
  405. this.fonts = fonts;
  406. }
  407. /**
  408. * Increments and returns the current page font count
  409. *
  410. * @return increment and return the current page font count
  411. */
  412. protected int incrementFontCount() {
  413. return ++fontCount;
  414. }
  415. /**
  416. * Returns the current page orientation
  417. *
  418. * @return the current page orientation
  419. */
  420. protected int getOrientation() {
  421. return orientation;
  422. }
  423. /**
  424. * Sets the current page orientation
  425. *
  426. * @param orientation the current page orientation
  427. */
  428. protected void setOrientation(int orientation) {
  429. this.orientation = orientation;
  430. }
  431. /** {@inheritDoc} */
  432. public Object clone() {
  433. AFPPagePaintingState state = new AFPPagePaintingState();
  434. state.width = this.width;
  435. state.height = this.height;
  436. state.orientation = this.orientation;
  437. state.fonts = new AFPPageFonts(this.fonts);
  438. state.fontCount = this.fontCount;
  439. return state;
  440. }
  441. /** {@inheritDoc} */
  442. public String toString() {
  443. return "AFPPagePaintingState{width=" + width
  444. + ", height=" + height
  445. + ", orientation=" + orientation
  446. + ", fonts=" + fonts
  447. + ", fontCount=" + fontCount
  448. + "}";
  449. }
  450. }
  451. /**
  452. * Block level state data
  453. */
  454. private class AFPData extends org.apache.fop.util.AbstractPaintingState.AbstractData {
  455. private static final long serialVersionUID = -1789481244175275686L;
  456. /** The current fill status */
  457. private boolean filled = false;
  458. private String imageUri = null;
  459. /** {@inheritDoc} */
  460. public Object clone() {
  461. AFPData obj = (AFPData)super.clone();
  462. obj.filled = this.filled;
  463. obj.imageUri = this.imageUri;
  464. return obj;
  465. }
  466. /** {@inheritDoc} */
  467. public String toString() {
  468. return "AFPData{" + super.toString()
  469. + ", filled=" + filled
  470. + ", imageUri=" + imageUri
  471. + "}";
  472. }
  473. /** {@inheritDoc} */
  474. protected AbstractData instantiate() {
  475. return new AFPData();
  476. }
  477. }
  478. }