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.

HwmfMisc.java 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  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. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.hwmf.record;
  16. import java.awt.Color;
  17. import java.awt.geom.Dimension2D;
  18. import java.awt.image.BufferedImage;
  19. import java.io.IOException;
  20. import org.apache.poi.hwmf.draw.HwmfDrawProperties;
  21. import org.apache.poi.hwmf.draw.HwmfGraphics;
  22. import org.apache.poi.hwmf.record.HwmfFill.ColorUsage;
  23. import org.apache.poi.hwmf.record.HwmfFill.HwmfImageRecord;
  24. import org.apache.poi.hwmf.record.HwmfMisc.WmfSetBkMode.HwmfBkMode;
  25. import org.apache.poi.util.Dimension2DDouble;
  26. import org.apache.poi.util.LittleEndianConsts;
  27. import org.apache.poi.util.LittleEndianInputStream;
  28. public class HwmfMisc {
  29. /**
  30. * The META_SAVEDC record saves the playback device context for later retrieval.
  31. */
  32. public static class WmfSaveDc implements HwmfRecord {
  33. @Override
  34. public HwmfRecordType getWmfRecordType() {
  35. return HwmfRecordType.saveDc;
  36. }
  37. @Override
  38. public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
  39. return 0;
  40. }
  41. @Override
  42. public void draw(HwmfGraphics ctx) {
  43. ctx.saveProperties();
  44. }
  45. @Override
  46. public String toString() {
  47. return "{}";
  48. }
  49. }
  50. /**
  51. * The META_SETRELABS record is reserved and not supported.
  52. */
  53. public static class WmfSetRelabs implements HwmfRecord {
  54. public HwmfRecordType getWmfRecordType() {
  55. return HwmfRecordType.setRelabs;
  56. }
  57. public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
  58. return 0;
  59. }
  60. @Override
  61. public void draw(HwmfGraphics ctx) {
  62. }
  63. }
  64. /**
  65. * The META_RESTOREDC record restores the playback device context from a previously saved device
  66. * context.
  67. */
  68. public static class WmfRestoreDc implements HwmfRecord {
  69. /**
  70. * nSavedDC (2 bytes): A 16-bit signed integer that defines the saved state to be restored. If this
  71. * member is positive, nSavedDC represents a specific instance of the state to be restored. If
  72. * this member is negative, nSavedDC represents an instance relative to the current state.
  73. */
  74. protected int nSavedDC;
  75. @Override
  76. public HwmfRecordType getWmfRecordType() {
  77. return HwmfRecordType.restoreDc;
  78. }
  79. @Override
  80. public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
  81. nSavedDC = leis.readShort();
  82. return LittleEndianConsts.SHORT_SIZE;
  83. }
  84. @Override
  85. public void draw(HwmfGraphics ctx) {
  86. ctx.restoreProperties(nSavedDC);
  87. }
  88. @Override
  89. public String toString() {
  90. return "{ nSavedDC: "+nSavedDC+" }";
  91. }
  92. }
  93. /**
  94. * The META_SETBKCOLOR record sets the background color in the playback device context to a
  95. * specified color, or to the nearest physical color if the device cannot represent the specified color.
  96. */
  97. public static class WmfSetBkColor implements HwmfRecord {
  98. protected final HwmfColorRef colorRef = new HwmfColorRef();
  99. @Override
  100. public HwmfRecordType getWmfRecordType() {
  101. return HwmfRecordType.setBkColor;
  102. }
  103. @Override
  104. public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
  105. return colorRef.init(leis);
  106. }
  107. @Override
  108. public void draw(HwmfGraphics ctx) {
  109. ctx.getProperties().setBackgroundColor(colorRef);
  110. }
  111. @Override
  112. public String toString() {
  113. return "{ colorRef: "+colorRef+" }";
  114. }
  115. }
  116. /**
  117. * The META_SETBKMODE record defines the background raster operation mix mode in the playback
  118. * device context. The background mix mode is the mode for combining pens, text, hatched brushes,
  119. * and interiors of filled objects with background colors on the output surface.
  120. */
  121. public static class WmfSetBkMode implements HwmfRecord {
  122. /**
  123. * A 16-bit unsigned integer that defines background mix mode.
  124. */
  125. public enum HwmfBkMode {
  126. TRANSPARENT(0x0001), OPAQUE(0x0002);
  127. int flag;
  128. HwmfBkMode(int flag) {
  129. this.flag = flag;
  130. }
  131. public static HwmfBkMode valueOf(int flag) {
  132. for (HwmfBkMode bs : values()) {
  133. if (bs.flag == flag) return bs;
  134. }
  135. return null;
  136. }
  137. }
  138. protected HwmfBkMode bkMode;
  139. public HwmfRecordType getWmfRecordType() {
  140. return HwmfRecordType.setBkMode;
  141. }
  142. public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
  143. bkMode = HwmfBkMode.valueOf(leis.readUShort());
  144. return LittleEndianConsts.SHORT_SIZE;
  145. }
  146. @Override
  147. public void draw(HwmfGraphics ctx) {
  148. ctx.getProperties().setBkMode(bkMode);
  149. }
  150. @Override
  151. public String toString() {
  152. return "{ bkMode: '"+bkMode+"' }";
  153. }
  154. }
  155. /**
  156. * The META_SETLAYOUT record defines the layout orientation in the playback device context.
  157. * The layout orientation determines the direction in which text and graphics are drawn
  158. */
  159. public static class WmfSetLayout implements HwmfRecord {
  160. /**
  161. * A 16-bit unsigned integer that defines the layout of text and graphics.
  162. * LAYOUT_LTR = 0x0000
  163. * LAYOUT_RTL = 0x0001
  164. * LAYOUT_BITMAPORIENTATIONPRESERVED = 0x0008
  165. */
  166. private int layout;
  167. @Override
  168. public HwmfRecordType getWmfRecordType() {
  169. return HwmfRecordType.setLayout;
  170. }
  171. @Override
  172. public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
  173. layout = leis.readUShort();
  174. // A 16-bit field that MUST be ignored.
  175. /*int reserved =*/ leis.readShort();
  176. return 2*LittleEndianConsts.SHORT_SIZE;
  177. }
  178. @Override
  179. public void draw(HwmfGraphics ctx) {
  180. }
  181. }
  182. /**
  183. * The META_SETMAPMODE record defines the mapping mode in the playback device context.
  184. * The mapping mode defines the unit of measure used to transform page-space units into
  185. * device-space units, and also defines the orientation of the device's x and y axes.
  186. */
  187. public static class WmfSetMapMode implements HwmfRecord {
  188. protected HwmfMapMode mapMode;
  189. @Override
  190. public HwmfRecordType getWmfRecordType() {
  191. return HwmfRecordType.setMapMode;
  192. }
  193. @Override
  194. public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
  195. mapMode = HwmfMapMode.valueOf(leis.readUShort());
  196. return LittleEndianConsts.SHORT_SIZE;
  197. }
  198. @Override
  199. public void draw(HwmfGraphics ctx) {
  200. ctx.getProperties().setMapMode(mapMode);
  201. ctx.updateWindowMapMode();
  202. }
  203. @Override
  204. public String toString() {
  205. return "{ mapMode: '"+mapMode+"' }";
  206. }
  207. }
  208. /**
  209. * The META_SETMAPPERFLAGS record defines the algorithm that the font mapper uses when it maps
  210. * logical fonts to physical fonts.
  211. */
  212. public static class WmfSetMapperFlags implements HwmfRecord {
  213. /**
  214. * A 32-bit unsigned integer that defines whether the font mapper should attempt to
  215. * match a font's aspect ratio to the current device's aspect ratio. If bit 0 is
  216. * set, the font mapper SHOULD select only fonts that match the aspect ratio of the
  217. * output device, as it is currently defined in the playback device context.
  218. */
  219. private long mapperValues;
  220. @Override
  221. public HwmfRecordType getWmfRecordType() {
  222. return HwmfRecordType.setMapperFlags;
  223. }
  224. @Override
  225. public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
  226. mapperValues = leis.readUInt();
  227. return LittleEndianConsts.INT_SIZE;
  228. }
  229. @Override
  230. public void draw(HwmfGraphics ctx) {
  231. }
  232. @Override
  233. public String toString() {
  234. return "{ mapperValues: "+mapperValues+" }";
  235. }
  236. }
  237. /**
  238. * The META_SETROP2 record defines the foreground raster operation mix mode in the playback device
  239. * context. The foreground mix mode is the mode for combining pens and interiors of filled objects with
  240. * foreground colors on the output surface.
  241. */
  242. public static class WmfSetRop2 implements HwmfRecord {
  243. /** An unsigned integer that defines the foreground binary raster operation mixing mode */
  244. protected HwmfBinaryRasterOp drawMode;
  245. @Override
  246. public HwmfRecordType getWmfRecordType() {
  247. return HwmfRecordType.setRop2;
  248. }
  249. @Override
  250. public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
  251. drawMode = HwmfBinaryRasterOp.valueOf(leis.readUShort());
  252. return LittleEndianConsts.SHORT_SIZE;
  253. }
  254. @Override
  255. public void draw(HwmfGraphics ctx) {
  256. }
  257. @Override
  258. public String toString() {
  259. return "{ drawMode: '"+drawMode+"' }";
  260. }
  261. }
  262. /**
  263. * The META_SETSTRETCHBLTMODE record defines the bitmap stretching mode in the playback device
  264. * context.
  265. */
  266. public static class WmfSetStretchBltMode implements HwmfRecord {
  267. public enum StretchBltMode {
  268. /**
  269. * Performs a Boolean AND operation by using the color values for the eliminated and existing pixels.
  270. * If the bitmap is a monochrome bitmap, this mode preserves black pixels at the expense of white pixels.
  271. *
  272. * EMF name: STRETCH_ANDSCANS
  273. */
  274. BLACKONWHITE(0x0001),
  275. /**
  276. * Performs a Boolean OR operation by using the color values for the eliminated and existing pixels.
  277. * If the bitmap is a monochrome bitmap, this mode preserves white pixels at the expense of black pixels.
  278. *
  279. * EMF name: STRETCH_ORSCANS
  280. */
  281. WHITEONBLACK(0x0002),
  282. /**
  283. * Deletes the pixels. This mode deletes all eliminated lines of pixels without trying
  284. * to preserve their information.
  285. *
  286. * EMF name: STRETCH_DELETESCANS
  287. */
  288. COLORONCOLOR(0x0003),
  289. /**
  290. * Maps pixels from the source rectangle into blocks of pixels in the destination rectangle.
  291. * The average color over the destination block of pixels approximates the color of the source
  292. * pixels.
  293. *
  294. * After setting the HALFTONE stretching mode, the brush origin MUST be set to avoid misalignment
  295. * artifacts - in EMF this is done via EmfSetBrushOrgEx
  296. *
  297. * EMF name: STRETCH_HALFTONE
  298. */
  299. HALFTONE(0x0004);
  300. public final int flag;
  301. StretchBltMode(int flag) {
  302. this.flag = flag;
  303. }
  304. public static StretchBltMode valueOf(int flag) {
  305. for (StretchBltMode bs : values()) {
  306. if (bs.flag == flag) return bs;
  307. }
  308. return null;
  309. }
  310. }
  311. protected StretchBltMode stretchBltMode;
  312. @Override
  313. public HwmfRecordType getWmfRecordType() {
  314. return HwmfRecordType.setStretchBltMode;
  315. }
  316. @Override
  317. public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
  318. stretchBltMode = StretchBltMode.valueOf(leis.readUShort());
  319. return LittleEndianConsts.SHORT_SIZE;
  320. }
  321. @Override
  322. public void draw(HwmfGraphics ctx) {
  323. }
  324. @Override
  325. public String toString() {
  326. return "{ stretchBltMode: '"+stretchBltMode+"' }";
  327. }
  328. }
  329. /**
  330. * The META_DIBCREATEPATTERNBRUSH record creates a Brush Object with a
  331. * pattern specified by a DeviceIndependentBitmap (DIB) Object
  332. */
  333. public static class WmfDibCreatePatternBrush implements HwmfRecord, HwmfImageRecord, HwmfObjectTableEntry {
  334. protected HwmfBrushStyle style;
  335. /**
  336. * A 16-bit unsigned integer that defines whether the Colors field of a DIB
  337. * Object contains explicit RGB values, or indexes into a palette.
  338. *
  339. * If the Style field specifies BS_PATTERN, a ColorUsage value of DIB_RGB_COLORS MUST be
  340. * used regardless of the contents of this field.
  341. *
  342. * If the Style field specified anything but BS_PATTERN, this field MUST be one of the ColorUsage values.
  343. */
  344. protected ColorUsage colorUsage;
  345. protected HwmfBitmapDib patternDib;
  346. private HwmfBitmap16 pattern16;
  347. @Override
  348. public HwmfRecordType getWmfRecordType() {
  349. return HwmfRecordType.dibCreatePatternBrush;
  350. }
  351. @Override
  352. public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
  353. style = HwmfBrushStyle.valueOf(leis.readUShort());
  354. colorUsage = ColorUsage.valueOf(leis.readUShort());
  355. int size = 2*LittleEndianConsts.SHORT_SIZE;
  356. switch (style) {
  357. case BS_SOLID:
  358. case BS_NULL:
  359. case BS_DIBPATTERN:
  360. case BS_DIBPATTERNPT:
  361. case BS_HATCHED:
  362. case BS_PATTERN:
  363. patternDib = new HwmfBitmapDib();
  364. size += patternDib.init(leis, (int)(recordSize-6-size));
  365. break;
  366. case BS_INDEXED:
  367. case BS_DIBPATTERN8X8:
  368. case BS_MONOPATTERN:
  369. case BS_PATTERN8X8:
  370. throw new RuntimeException("pattern not supported");
  371. }
  372. return size;
  373. }
  374. @Override
  375. public void draw(HwmfGraphics ctx) {
  376. ctx.addObjectTableEntry(this);
  377. }
  378. @Override
  379. public void applyObject(HwmfGraphics ctx) {
  380. if (patternDib != null && !patternDib.isValid()) {
  381. return;
  382. }
  383. HwmfDrawProperties prop = ctx.getProperties();
  384. prop.setBrushStyle(style);
  385. prop.setBrushBitmap(getImage(prop.getBrushColor().getColor(), prop.getBackgroundColor().getColor(),
  386. prop.getBkMode() == HwmfBkMode.TRANSPARENT));
  387. }
  388. @Override
  389. public BufferedImage getImage(Color foreground, Color background, boolean hasAlpha) {
  390. if (patternDib != null && patternDib.isValid()) {
  391. return patternDib.getImage(foreground, background, hasAlpha);
  392. } else if (pattern16 != null) {
  393. return pattern16.getImage();
  394. } else {
  395. return null;
  396. }
  397. }
  398. @Override
  399. public byte[] getBMPData() {
  400. if (patternDib != null && patternDib.isValid()) {
  401. return patternDib.getBMPData();
  402. } else if (pattern16 != null) {
  403. return null;
  404. } else {
  405. return null;
  406. }
  407. }
  408. }
  409. /**
  410. * The META_DELETEOBJECT record deletes an object, including Bitmap16, Brush,
  411. * DeviceIndependentBitmap, Font, Palette, Pen, and Region. After the object is deleted,
  412. * its index in the WMF Object Table is no longer valid but is available to be reused.
  413. */
  414. public static class WmfDeleteObject implements HwmfRecord {
  415. /**
  416. * A 16-bit unsigned integer used to index into the WMF Object Table to
  417. * get the object to be deleted.
  418. */
  419. protected int objectIndex;
  420. @Override
  421. public HwmfRecordType getWmfRecordType() {
  422. return HwmfRecordType.deleteObject;
  423. }
  424. @Override
  425. public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
  426. objectIndex = leis.readUShort();
  427. return LittleEndianConsts.SHORT_SIZE;
  428. }
  429. @Override
  430. public void draw(HwmfGraphics ctx) {
  431. /* TODO:
  432. * The object specified by this record MUST be deleted from the EMF Object Table.
  433. * If the deleted object is currently selected in the playback device context,
  434. * the default object for that graphics property MUST be restored.
  435. */
  436. ctx.unsetObjectTableEntry(objectIndex);
  437. }
  438. @Override
  439. public String toString() {
  440. return "{ index: "+objectIndex+" }";
  441. }
  442. }
  443. public static class WmfCreatePatternBrush implements HwmfRecord, HwmfObjectTableEntry {
  444. private HwmfBitmap16 pattern;
  445. @Override
  446. public HwmfRecordType getWmfRecordType() {
  447. return HwmfRecordType.createPatternBrush;
  448. }
  449. @Override
  450. public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
  451. pattern = new HwmfBitmap16(true);
  452. return pattern.init(leis);
  453. }
  454. @Override
  455. public void draw(HwmfGraphics ctx) {
  456. ctx.addObjectTableEntry(this);
  457. }
  458. @Override
  459. public void applyObject(HwmfGraphics ctx) {
  460. HwmfDrawProperties dp = ctx.getProperties();
  461. dp.setBrushBitmap(pattern.getImage());
  462. dp.setBrushStyle(HwmfBrushStyle.BS_PATTERN);
  463. }
  464. }
  465. public static class WmfCreatePenIndirect implements HwmfRecord, HwmfObjectTableEntry {
  466. protected HwmfPenStyle penStyle;
  467. protected final Dimension2D dimension = new Dimension2DDouble();
  468. /**
  469. * A 32-bit ColorRef Object that specifies the pen color value.
  470. */
  471. protected final HwmfColorRef colorRef = new HwmfColorRef();
  472. @Override
  473. public HwmfRecordType getWmfRecordType() {
  474. return HwmfRecordType.createPenIndirect;
  475. }
  476. @Override
  477. public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
  478. penStyle = HwmfPenStyle.valueOf(leis.readUShort());
  479. // A 32-bit PointS Object that specifies a point for the object dimensions.
  480. // The x-coordinate is the pen width. The y-coordinate is ignored.
  481. int xWidth = leis.readShort();
  482. int yWidth = leis.readShort();
  483. dimension.setSize(xWidth, yWidth);
  484. int size = colorRef.init(leis);
  485. return size+3*LittleEndianConsts.SHORT_SIZE;
  486. }
  487. @Override
  488. public void draw(HwmfGraphics ctx) {
  489. ctx.addObjectTableEntry(this);
  490. }
  491. @Override
  492. public void applyObject(HwmfGraphics ctx) {
  493. HwmfDrawProperties p = ctx.getProperties();
  494. p.setPenStyle(penStyle);
  495. p.setPenColor(colorRef);
  496. p.setPenWidth(dimension.getWidth());
  497. }
  498. @Override
  499. public String toString() {
  500. return
  501. "{ penStyle: "+penStyle+
  502. ", dimension: { width: "+dimension.getWidth()+", height: "+dimension.getHeight()+" }"+
  503. ", colorRef: "+colorRef+"}";
  504. }
  505. }
  506. /**
  507. * The META_CREATEBRUSHINDIRECT record creates a Brush Object
  508. * from a LogBrush Object.
  509. *
  510. * The following table shows the relationship between values in the BrushStyle,
  511. * ColorRef and BrushHatch fields in a LogBrush Object. Only supported brush styles are listed.
  512. *
  513. * <table>
  514. * <tr>
  515. * <th>BrushStyle</th>
  516. * <th>ColorRef</th>
  517. * <th>BrushHatch</th>
  518. * </tr>
  519. * <tr>
  520. * <td>BS_SOLID</td>
  521. * <td>SHOULD be a ColorRef Object, which determines the color of the brush.</td>
  522. * <td>Not used, and SHOULD be ignored.</td>
  523. * </tr>
  524. * <tr>
  525. * <td>BS_NULL</td>
  526. * <td>Not used, and SHOULD be ignored.</td>
  527. * <td>Not used, and SHOULD be ignored.</td>
  528. * </tr>
  529. * <tr>
  530. * <td>BS_PATTERN</td>
  531. * <td>Not used, and SHOULD be ignored.</td>
  532. * <td>Not used. A default object, such as a solidcolor black Brush Object, MAY be created.</td>
  533. * </tr>
  534. * <tr>
  535. * <td>BS_DIBPATTERN</td>
  536. * <td>Not used, and SHOULD be ignored.</td>
  537. * <td>Not used. A default object, such as a solidcolor black Brush Object, MAY be created</td>
  538. * </tr>
  539. * <tr>
  540. * <td>BS_DIBPATTERNPT</td>
  541. * <td>Not used, and SHOULD be ignored.</td>
  542. * <td>Not used. A default object, such as a solidcolor black Brush Object, MAY be created.</td>
  543. * </tr>
  544. * <tr>
  545. * <td>BS_HATCHED</td>
  546. * <td>SHOULD be a ColorRef Object, which determines the foreground color of the hatch pattern.</td>
  547. * <td>A value from the {@link HwmfHatchStyle} Enumeration that specifies the orientation of lines used to create the hatch.</td>
  548. * </tr>
  549. * </table>
  550. */
  551. public static class WmfCreateBrushIndirect implements HwmfRecord, HwmfObjectTableEntry {
  552. protected HwmfBrushStyle brushStyle;
  553. protected HwmfColorRef colorRef;
  554. protected HwmfHatchStyle brushHatch;
  555. @Override
  556. public HwmfRecordType getWmfRecordType() {
  557. return HwmfRecordType.createBrushIndirect;
  558. }
  559. @Override
  560. public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
  561. brushStyle = HwmfBrushStyle.valueOf(leis.readUShort());
  562. colorRef = new HwmfColorRef();
  563. int size = colorRef.init(leis);
  564. brushHatch = HwmfHatchStyle.valueOf(leis.readUShort());
  565. return size+2*LittleEndianConsts.SHORT_SIZE;
  566. }
  567. @Override
  568. public void draw(HwmfGraphics ctx) {
  569. ctx.addObjectTableEntry(this);
  570. }
  571. @Override
  572. public void applyObject(HwmfGraphics ctx) {
  573. HwmfDrawProperties p = ctx.getProperties();
  574. p.setBrushStyle(brushStyle);
  575. p.setBrushColor(colorRef);
  576. p.setBrushHatch(brushHatch);
  577. }
  578. @Override
  579. public String toString() {
  580. return
  581. "{ brushStyle: '"+brushStyle+"'"+
  582. ", colorRef: "+colorRef+
  583. ", brushHatch: '"+brushHatch+"' }";
  584. }
  585. }
  586. }