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

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