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.

HwmfFont.java 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  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.io.IOException;
  17. import java.nio.charset.Charset;
  18. import java.nio.charset.UnsupportedCharsetException;
  19. import org.apache.poi.util.LittleEndianConsts;
  20. import org.apache.poi.util.LittleEndianInputStream;
  21. import org.apache.poi.util.POILogFactory;
  22. import org.apache.poi.util.POILogger;
  23. /**
  24. * The Font object specifies the attributes of a logical font
  25. */
  26. public class HwmfFont {
  27. private static final POILogger logger = POILogFactory.getLogger(HwmfFont.class);
  28. public enum WmfCharset {
  29. /** Specifies the English character set. */
  30. ANSI_CHARSET(0x00000000, "Cp1252"),
  31. /**
  32. * Specifies a character set based on the current system locale;
  33. * for example, when the system locale is United States English,
  34. * the default character set is ANSI_CHARSET.
  35. */
  36. DEFAULT_CHARSET(0x00000001, "Cp1252"),
  37. /** Specifies a character set of symbols. */
  38. SYMBOL_CHARSET(0x00000002, ""),
  39. /** Specifies the Apple Macintosh character set. */
  40. MAC_CHARSET(0x0000004D, "MacRoman"),
  41. /** Specifies the Japanese character set. */
  42. SHIFTJIS_CHARSET(0x00000080, "Shift_JIS"),
  43. /** Also spelled "Hangeul". Specifies the Hangul Korean character set. */
  44. HANGUL_CHARSET(0x00000081, "cp949"),
  45. /** Also spelled "Johap". Specifies the Johab Korean character set. */
  46. JOHAB_CHARSET(0x00000082, "x-Johab"),
  47. /** Specifies the "simplified" Chinese character set for People's Republic of China. */
  48. GB2312_CHARSET(0x00000086, "GB2312"),
  49. /**
  50. * Specifies the "traditional" Chinese character set, used mostly in
  51. * Taiwan and in the Hong Kong and Macao Special Administrative Regions.
  52. */
  53. CHINESEBIG5_CHARSET(0x00000088, "Big5"),
  54. /** Specifies the Greek character set. */
  55. GREEK_CHARSET(0x000000A1, "Cp1253"),
  56. /** Specifies the Turkish character set. */
  57. TURKISH_CHARSET(0x000000A2, "Cp1254"),
  58. /** Specifies the Vietnamese character set. */
  59. VIETNAMESE_CHARSET(0x000000A3, "Cp1258"),
  60. /** Specifies the Hebrew character set. */
  61. HEBREW_CHARSET(0x000000B1, "Cp1255"),
  62. /** Specifies the Arabic character set. */
  63. ARABIC_CHARSET(0x000000B2, "Cp1256"),
  64. /** Specifies the Baltic (Northeastern European) character set. */
  65. BALTIC_CHARSET(0x000000BA, "Cp1257"),
  66. /** Specifies the Russian Cyrillic character set. */
  67. RUSSIAN_CHARSET(0x000000CC, "Cp1251"),
  68. /** Specifies the Thai character set. */
  69. THAI_CHARSET(0x000000DE, "x-windows-874"),
  70. /** Specifies a Eastern European character set. */
  71. EASTEUROPE_CHARSET(0x000000EE, "Cp1250"),
  72. /**
  73. * Specifies a mapping to one of the OEM code pages,
  74. * according to the current system locale setting.
  75. */
  76. OEM_CHARSET(0x000000FF, "Cp1252");
  77. int flag;
  78. Charset charset;
  79. WmfCharset(int flag, String javaCharsetName) {
  80. this.flag = flag;
  81. if (javaCharsetName.length() > 0) {
  82. try {
  83. charset = Charset.forName(javaCharsetName);
  84. return;
  85. } catch (UnsupportedCharsetException e) {
  86. logger.log(POILogger.WARN, "Unsupported charset: "+javaCharsetName);
  87. }
  88. }
  89. charset = null;
  90. }
  91. /**
  92. *
  93. * @return charset for the font or <code>null</code> if there is no matching charset or
  94. * if the charset is a &quot;default&quot;
  95. */
  96. public Charset getCharset() {
  97. return charset;
  98. }
  99. public static WmfCharset valueOf(int flag) {
  100. for (WmfCharset cs : values()) {
  101. if (cs.flag == flag) return cs;
  102. }
  103. return null;
  104. }
  105. }
  106. /**
  107. * The output precision defines how closely the output must match the requested font's height,
  108. * width, character orientation, escapement, pitch, and font type.
  109. */
  110. public enum WmfOutPrecision {
  111. /**
  112. * A value that specifies default behavior.
  113. */
  114. OUT_DEFAULT_PRECIS(0x00000000),
  115. /**
  116. * A value that is returned when rasterized fonts are enumerated.
  117. */
  118. OUT_STRING_PRECIS(0x00000001),
  119. /**
  120. * A value that is returned when TrueType and other outline fonts, and
  121. * vector fonts are enumerated.
  122. */
  123. OUT_STROKE_PRECIS(0x00000003),
  124. /**
  125. * A value that specifies the choice of a TrueType font when the system
  126. * contains multiple fonts with the same name.
  127. */
  128. OUT_TT_PRECIS(0x00000004),
  129. /**
  130. * A value that specifies the choice of a device font when the system
  131. * contains multiple fonts with the same name.
  132. */
  133. OUT_DEVICE_PRECIS(0x00000005),
  134. /**
  135. * A value that specifies the choice of a rasterized font when the system
  136. * contains multiple fonts with the same name.
  137. */
  138. OUT_RASTER_PRECIS(0x00000006),
  139. /**
  140. * A value that specifies the requirement for only TrueType fonts. If
  141. * there are no TrueType fonts installed in the system, default behavior is specified.
  142. */
  143. OUT_TT_ONLY_PRECIS(0x00000007),
  144. /**
  145. * A value that specifies the requirement for TrueType and other outline fonts.
  146. */
  147. OUT_OUTLINE_PRECIS (0x00000008),
  148. /**
  149. * A value that specifies a preference for TrueType and other outline fonts.
  150. */
  151. OUT_SCREEN_OUTLINE_PRECIS (0x00000009),
  152. /**
  153. * A value that specifies a requirement for only PostScript fonts. If there
  154. * are no PostScript fonts installed in the system, default behavior is specified.
  155. */
  156. OUT_PS_ONLY_PRECIS (0x0000000A);
  157. int flag;
  158. WmfOutPrecision(int flag) {
  159. this.flag = flag;
  160. }
  161. static WmfOutPrecision valueOf(int flag) {
  162. for (WmfOutPrecision op : values()) {
  163. if (op.flag == flag) return op;
  164. }
  165. return null;
  166. }
  167. }
  168. /**
  169. * ClipPrecision Flags specify clipping precision, which defines how to clip characters that are
  170. * partially outside a clipping region. These flags can be combined to specify multiple options.
  171. */
  172. public enum WmfClipPrecision {
  173. /**
  174. * Specifies that default clipping MUST be used.
  175. */
  176. CLIP_DEFAULT_PRECIS (0x00000000),
  177. /**
  178. * This value SHOULD NOT be used.
  179. */
  180. CLIP_CHARACTER_PRECIS (0x00000001),
  181. /**
  182. * This value MAY be returned when enumerating rasterized, TrueType and vector fonts.
  183. */
  184. CLIP_STROKE_PRECIS (0x00000002),
  185. /**
  186. * This value is used to control font rotation, as follows:
  187. * If set, the rotation for all fonts SHOULD be determined by the orientation of the coordinate system;
  188. * that is, whether the orientation is left-handed or right-handed.
  189. *
  190. * If clear, device fonts SHOULD rotate counterclockwise, but the rotation of other fonts
  191. * SHOULD be determined by the orientation of the coordinate system.
  192. */
  193. CLIP_LH_ANGLES (0x00000010),
  194. /**
  195. * This value SHOULD NOT be used.
  196. */
  197. CLIP_TT_ALWAYS (0x00000020),
  198. /**
  199. * This value specifies that font association SHOULD< be turned off.
  200. */
  201. CLIP_DFA_DISABLE (0x00000040),
  202. /**
  203. * This value specifies that font embedding MUST be used to render document content;
  204. * embedded fonts are read-only.
  205. */
  206. CLIP_EMBEDDED (0x00000080);
  207. int flag;
  208. WmfClipPrecision(int flag) {
  209. this.flag = flag;
  210. }
  211. static WmfClipPrecision valueOf(int flag) {
  212. for (WmfClipPrecision cp : values()) {
  213. if (cp.flag == flag) return cp;
  214. }
  215. return null;
  216. }
  217. }
  218. /**
  219. * The output quality defines how carefully to attempt to match the logical font attributes to those of an actual
  220. * physical font.
  221. */
  222. public enum WmfFontQuality {
  223. /**
  224. * Specifies that the character quality of the font does not matter, so DRAFT_QUALITY can be used.
  225. */
  226. DEFAULT_QUALITY (0x00),
  227. /**
  228. * Specifies that the character quality of the font is less important than the
  229. * matching of logical attribuetes. For rasterized fonts, scaling SHOULD be enabled, which
  230. * means that more font sizes are available.
  231. */
  232. DRAFT_QUALITY (0x01),
  233. /**
  234. * Specifies that the character quality of the font is more important than the
  235. * matching of logical attributes. For rasterized fonts, scaling SHOULD be disabled, and the font
  236. * closest in size SHOULD be chosen.
  237. */
  238. PROOF_QUALITY (0x02),
  239. /**
  240. * Specifies that anti-aliasing SHOULD NOT be used when rendering text.
  241. */
  242. NONANTIALIASED_QUALITY (0x03),
  243. /**
  244. * Specifies that anti-aliasing SHOULD be used when rendering text, if the font supports it.
  245. */
  246. ANTIALIASED_QUALITY (0x04),
  247. /**
  248. * Specifies that ClearType anti-aliasing SHOULD be used when rendering text, if the font supports it.
  249. *
  250. * Fonts that do not support ClearType anti-aliasing include type 1 fonts, PostScript fonts,
  251. * OpenType fonts without TrueType outlines, rasterized fonts, vector fonts, and device fonts.
  252. */
  253. CLEARTYPE_QUALITY (0x05);
  254. int flag;
  255. WmfFontQuality(int flag) {
  256. this.flag = flag;
  257. }
  258. static WmfFontQuality valueOf(int flag) {
  259. for (WmfFontQuality fq : values()) {
  260. if (fq.flag == flag) return fq;
  261. }
  262. return null;
  263. }
  264. }
  265. /**
  266. * A property of a font that describes its general appearance.
  267. */
  268. public enum WmfFontFamilyClass {
  269. /**
  270. * The default font is specified, which is implementation-dependent.
  271. */
  272. FF_DONTCARE (0x00),
  273. /**
  274. * Fonts with variable stroke widths, which are proportional to the actual widths of
  275. * the glyphs, and which have serifs. "MS Serif" is an example.
  276. */
  277. FF_ROMAN (0x01),
  278. /**
  279. * Fonts with variable stroke widths, which are proportional to the actual widths of the
  280. * glyphs, and which do not have serifs. "MS Sans Serif" is an example.
  281. */
  282. FF_SWISS (0x02),
  283. /**
  284. * Fonts with constant stroke width, with or without serifs. Fixed-width fonts are
  285. * usually modern. "Pica", "Elite", and "Courier New" are examples.
  286. */
  287. FF_MODERN (0x03),
  288. /**
  289. * Fonts designed to look like handwriting. "Script" and "Cursive" are examples.
  290. */
  291. FF_SCRIPT (0x04),
  292. /**
  293. * Novelty fonts. "Old English" is an example.
  294. */
  295. FF_DECORATIVE (0x05);
  296. int flag;
  297. WmfFontFamilyClass(int flag) {
  298. this.flag = flag;
  299. }
  300. static WmfFontFamilyClass valueOf(int flag) {
  301. for (WmfFontFamilyClass ff : values()) {
  302. if (ff.flag == flag) return ff;
  303. }
  304. return null;
  305. }
  306. }
  307. /**
  308. * A property of a font that describes the pitch, of the characters.
  309. */
  310. public enum WmfFontPitch {
  311. /**
  312. * The default pitch, which is implementation-dependent.
  313. */
  314. DEFAULT_PITCH (0x00),
  315. /**
  316. * A fixed pitch, which means that all the characters in the font occupy the same
  317. * width when output in a string.
  318. */
  319. FIXED_PITCH (0x01),
  320. /**
  321. * A variable pitch, which means that the characters in the font occupy widths
  322. * that are proportional to the actual widths of the glyphs when output in a string. For example,
  323. * the "i" and space characters usually have much smaller widths than a "W" or "O" character.
  324. */
  325. VARIABLE_PITCH (0x02);
  326. int flag;
  327. WmfFontPitch(int flag) {
  328. this.flag = flag;
  329. }
  330. static WmfFontPitch valueOf(int flag) {
  331. for (WmfFontPitch fp : values()) {
  332. if (fp.flag == flag) return fp;
  333. }
  334. return null;
  335. }
  336. }
  337. /**
  338. * A 16-bit signed integer that specifies the height, in logical units, of the font's
  339. * character cell. The character height is computed as the character cell height minus the
  340. * internal leading. The font mapper SHOULD interpret the height as follows.
  341. *
  342. * negative value:
  343. * The font mapper SHOULD transform this value into device units and match its
  344. * absolute value against the character height of available fonts.
  345. *
  346. * zero value:
  347. * A default height value MUST be used when creating a physical font.
  348. *
  349. * positive value:
  350. * The font mapper SHOULD transform this value into device units and match it
  351. * against the cell height of available fonts.
  352. *
  353. * For all height comparisons, the font mapper SHOULD find the largest physical
  354. * font that does not exceed the requested size.
  355. */
  356. int height;
  357. /**
  358. * A 16-bit signed integer that defines the average width, in logical units, of
  359. * characters in the font. If Width is 0x0000, the aspect ratio of the device SHOULD be matched
  360. * against the digitization aspect ratio of the available fonts to find the closest match,
  361. * determined by the absolute value of the difference.
  362. */
  363. int width;
  364. /**
  365. * A 16-bit signed integer that defines the angle, in tenths of degrees, between the
  366. * escapement vector and the x-axis of the device. The escapement vector is parallel
  367. * to the base line of a row of text.
  368. */
  369. int escapement;
  370. /**
  371. * A 16-bit signed integer that defines the angle, in tenths of degrees,
  372. * between each character's base line and the x-axis of the device.
  373. */
  374. int orientation;
  375. /**
  376. * A 16-bit signed integer that defines the weight of the font in the range 0
  377. * through 1000. For example, 400 is normal and 700 is bold. If this value is 0x0000,
  378. * a default weight SHOULD be used.
  379. */
  380. int weight;
  381. /**
  382. * A 8-bit Boolean value that specifies the italic attribute of the font.
  383. * 0 = not italic / 1 = italic.
  384. */
  385. boolean italic;
  386. /**
  387. * An 8-bit Boolean value that specifies the underline attribute of the font.
  388. * 0 = not underlined / 1 = underlined
  389. */
  390. boolean underline;
  391. /**
  392. * An 8-bit Boolean value that specifies the strike out attribute of the font.
  393. * 0 = not striked out / 1 = striked out
  394. */
  395. boolean strikeOut;
  396. /**
  397. * An 8-bit unsigned integer that defines the character set.
  398. * It SHOULD be set to a value in the {@link WmfCharset} Enumeration.
  399. *
  400. * The DEFAULT_CHARSET value MAY be used to allow the name and size of a font to fully
  401. * describe the logical font. If the specified font name does not exist, a font in another character
  402. * set MAY be substituted. The DEFAULT_CHARSET value is set to a value based on the current
  403. * system locale. For example, when the system locale is United States, it is set to ANSI_CHARSET.
  404. * If a typeface name in the FaceName field is specified, the CharSet value MUST match the
  405. * character set of that typeface.
  406. */
  407. WmfCharset charSet;
  408. /**
  409. * An 8-bit unsigned integer that defines the output precision.
  410. */
  411. WmfOutPrecision outPrecision;
  412. /**
  413. * An 8-bit unsigned integer that defines the clipping precision.
  414. * These flags can be combined to specify multiple options.
  415. *
  416. * @see WmfClipPrecision
  417. */
  418. WmfClipPrecision clipPrecision;
  419. /**
  420. * An 8-bit unsigned integer that defines the output quality.
  421. */
  422. WmfFontQuality quality;
  423. /**
  424. * A PitchAndFamily object that defines the pitch and the family of the font.
  425. * Font families specify the look of fonts in a general way and are intended for
  426. * specifying fonts when the exact typeface wanted is not available.
  427. */
  428. int pitchAndFamily;
  429. /**
  430. * Font families specify the look of fonts in a general way and are
  431. * intended for specifying fonts when the exact typeface wanted is not available.
  432. * (LSB 4 bits)
  433. */
  434. WmfFontFamilyClass family;
  435. /**
  436. * A property of a font that describes the pitch (MSB 2 bits)
  437. */
  438. WmfFontPitch pitch;
  439. /**
  440. * A null-terminated string of 8-bit Latin-1 [ISO/IEC-8859-1] ANSI
  441. * characters that specifies the typeface name of the font. The length of this string MUST NOT
  442. * exceed 32 8-bit characters, including the terminating null.
  443. */
  444. String facename;
  445. public int init(LittleEndianInputStream leis) throws IOException {
  446. height = leis.readShort();
  447. width = leis.readShort();
  448. escapement = leis.readShort();
  449. orientation = leis.readShort();
  450. weight = leis.readShort();
  451. italic = leis.readByte() != 0;
  452. underline = leis.readByte() != 0;
  453. strikeOut = leis.readByte() != 0;
  454. charSet = WmfCharset.valueOf(leis.readUByte());
  455. outPrecision = WmfOutPrecision.valueOf(leis.readUByte());
  456. clipPrecision = WmfClipPrecision.valueOf(leis.readUByte());
  457. quality = WmfFontQuality.valueOf(leis.readUByte());
  458. pitchAndFamily = leis.readUByte();
  459. byte buf[] = new byte[32], b, readBytes = 0;
  460. do {
  461. if (readBytes == 32) {
  462. throw new IOException("Font facename can't be determined.");
  463. }
  464. buf[readBytes++] = b = leis.readByte();
  465. } while (b != 0 && b != -1 && readBytes <= 32);
  466. facename = new String(buf, 0, readBytes-1, Charset.forName("ISO-8859-1"));
  467. return 5*LittleEndianConsts.SHORT_SIZE+8*LittleEndianConsts.BYTE_SIZE+readBytes;
  468. }
  469. public int getHeight() {
  470. return height;
  471. }
  472. public int getWidth() {
  473. return width;
  474. }
  475. public int getEscapement() {
  476. return escapement;
  477. }
  478. public int getOrientation() {
  479. return orientation;
  480. }
  481. public int getWeight() {
  482. return weight;
  483. }
  484. public boolean isItalic() {
  485. return italic;
  486. }
  487. public boolean isUnderline() {
  488. return underline;
  489. }
  490. public boolean isStrikeOut() {
  491. return strikeOut;
  492. }
  493. public WmfCharset getCharSet() {
  494. return charSet;
  495. }
  496. public WmfOutPrecision getOutPrecision() {
  497. return outPrecision;
  498. }
  499. public WmfClipPrecision getClipPrecision() {
  500. return clipPrecision;
  501. }
  502. public WmfFontQuality getQuality() {
  503. return quality;
  504. }
  505. public int getPitchAndFamily() {
  506. return pitchAndFamily;
  507. }
  508. public WmfFontFamilyClass getFamily() {
  509. return WmfFontFamilyClass.valueOf(pitchAndFamily & 0xF);
  510. }
  511. public WmfFontPitch getPitch() {
  512. return WmfFontPitch.valueOf((pitchAndFamily >>> 6) & 3);
  513. }
  514. public String getFacename() {
  515. return facename;
  516. }
  517. }