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.

FontFormatting.java 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  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.hssf.record.cf;
  16. import org.apache.poi.hssf.record.RecordInputStream;
  17. import org.apache.poi.util.BitField;
  18. import org.apache.poi.util.BitFieldFactory;
  19. import org.apache.poi.util.LittleEndian;
  20. /**
  21. * Font Formatting Block of the Conditional Formatting Rule Record.
  22. */
  23. public final class FontFormatting {
  24. private byte[] _rawData;
  25. private static final int OFFSET_FONT_NAME = 0;
  26. private static final int OFFSET_FONT_HEIGHT = 64;
  27. private static final int OFFSET_FONT_OPTIONS = 68;
  28. private static final int OFFSET_FONT_WEIGHT = 72;
  29. private static final int OFFSET_ESCAPEMENT_TYPE = 74;
  30. private static final int OFFSET_UNDERLINE_TYPE = 76;
  31. private static final int OFFSET_FONT_COLOR_INDEX = 80;
  32. private static final int OFFSET_OPTION_FLAGS = 88;
  33. private static final int OFFSET_ESCAPEMENT_TYPE_MODIFIED = 92;
  34. private static final int OFFSET_UNDERLINE_TYPE_MODIFIED = 96;
  35. private static final int OFFSET_FONT_WEIGHT_MODIFIED = 100;
  36. private static final int OFFSET_NOT_USED1 = 104;
  37. private static final int OFFSET_NOT_USED2 = 108;
  38. private static final int OFFSET_NOT_USED3 = 112; // for some reason Excel always writes 0x7FFFFFFF at this offset
  39. private static final int OFFSET_FONT_FORMATING_END = 116;
  40. private static final int RAW_DATA_SIZE = 118;
  41. public final static int FONT_CELL_HEIGHT_PRESERVED = 0xFFFFFFFF;
  42. // FONT OPTIONS MASKS
  43. private static final BitField posture = BitFieldFactory.getInstance(0x00000002);
  44. private static final BitField outline = BitFieldFactory.getInstance(0x00000008);
  45. private static final BitField shadow = BitFieldFactory.getInstance(0x00000010);
  46. private static final BitField cancellation = BitFieldFactory.getInstance(0x00000080);
  47. // OPTION FLAGS MASKS
  48. private static final BitField styleModified = BitFieldFactory.getInstance(0x00000002);
  49. private static final BitField outlineModified = BitFieldFactory.getInstance(0x00000008);
  50. private static final BitField shadowModified = BitFieldFactory.getInstance(0x00000010);
  51. private static final BitField cancellationModified = BitFieldFactory.getInstance(0x00000080);
  52. /** Escapement type - None */
  53. public static final short SS_NONE = 0;
  54. /** Escapement type - Superscript */
  55. public static final short SS_SUPER = 1;
  56. /** Escapement type - Subscript */
  57. public static final short SS_SUB = 2;
  58. /** Underline type - None */
  59. public static final byte U_NONE = 0;
  60. /** Underline type - Single */
  61. public static final byte U_SINGLE = 1;
  62. /** Underline type - Double */
  63. public static final byte U_DOUBLE = 2;
  64. /** Underline type - Single Accounting */
  65. public static final byte U_SINGLE_ACCOUNTING = 0x21;
  66. /** Underline type - Double Accounting */
  67. public static final byte U_DOUBLE_ACCOUNTING = 0x22;
  68. /** Normal boldness (not bold) */
  69. private static final short FONT_WEIGHT_NORMAL = 0x190;
  70. /**
  71. * Bold boldness (bold)
  72. */
  73. private static final short FONT_WEIGHT_BOLD = 0x2bc;
  74. private FontFormatting(byte[] rawData) {
  75. _rawData = rawData;
  76. }
  77. public FontFormatting()
  78. {
  79. this(new byte[RAW_DATA_SIZE]);
  80. setFontHeight(-1);
  81. setItalic(false);
  82. setFontWieghtModified(false);
  83. setOutline(false);
  84. setShadow(false);
  85. setStrikeout(false);
  86. setEscapementType((short)0);
  87. setUnderlineType((byte)0);
  88. setFontColorIndex((short)-1);
  89. setFontStyleModified(false);
  90. setFontOutlineModified(false);
  91. setFontShadowModified(false);
  92. setFontCancellationModified(false);
  93. setEscapementTypeModified(false);
  94. setUnderlineTypeModified(false);
  95. setShort(OFFSET_FONT_NAME, 0);
  96. setInt(OFFSET_NOT_USED1, 0x00000001);
  97. setInt(OFFSET_NOT_USED2, 0x00000000);
  98. setInt(OFFSET_NOT_USED3, 0x7FFFFFFF);// for some reason Excel always writes 0x7FFFFFFF at this offset
  99. setShort(OFFSET_FONT_FORMATING_END, 0x0001);
  100. }
  101. /** Creates new FontFormatting */
  102. public FontFormatting(RecordInputStream in)
  103. {
  104. this(new byte[RAW_DATA_SIZE]);
  105. for (int i = 0; i < _rawData.length; i++)
  106. {
  107. _rawData[i] = in.readByte();
  108. }
  109. }
  110. private short getShort(int offset) {
  111. return LittleEndian.getShort( _rawData, offset);
  112. }
  113. private void setShort(int offset, int value) {
  114. LittleEndian.putShort( _rawData, offset, (short)value);
  115. }
  116. private int getInt(int offset) {
  117. return LittleEndian.getInt( _rawData, offset);
  118. }
  119. private void setInt(int offset, int value) {
  120. LittleEndian.putInt( _rawData, offset, value);
  121. }
  122. public byte[] getRawRecord()
  123. {
  124. return _rawData;
  125. }
  126. public int getDataLength() {
  127. return RAW_DATA_SIZE;
  128. }
  129. /**
  130. * sets the height of the font in 1/20th point units
  131. *
  132. *
  133. * @param height fontheight (in points/20); or -1 to preserve the cell font height
  134. */
  135. public void setFontHeight(int height)
  136. {
  137. setInt(OFFSET_FONT_HEIGHT, height);
  138. }
  139. /**
  140. * gets the height of the font in 1/20th point units
  141. *
  142. * @return fontheight (in points/20); or -1 if not modified
  143. */
  144. public int getFontHeight()
  145. {
  146. return getInt(OFFSET_FONT_HEIGHT);
  147. }
  148. private void setFontOption(boolean option, BitField field)
  149. {
  150. int options = getInt(OFFSET_FONT_OPTIONS);
  151. options = field.setBoolean(options, option);
  152. setInt(OFFSET_FONT_OPTIONS, options);
  153. }
  154. private boolean getFontOption(BitField field)
  155. {
  156. int options = getInt(OFFSET_FONT_OPTIONS);
  157. return field.isSet(options);
  158. }
  159. /**
  160. * set the font to be italics or not
  161. *
  162. * @param italic - whether the font is italics or not
  163. * @see #setFontOption(boolean, org.apache.poi.util.BitField)
  164. */
  165. public void setItalic(boolean italic)
  166. {
  167. setFontOption(italic, posture);
  168. }
  169. /**
  170. * get whether the font is to be italics or not
  171. *
  172. * @return italics - whether the font is italics or not
  173. * @see #getFontOption(org.apache.poi.util.BitField)
  174. */
  175. public boolean isItalic()
  176. {
  177. return getFontOption(posture);
  178. }
  179. public void setOutline(boolean on)
  180. {
  181. setFontOption(on, outline);
  182. }
  183. public boolean isOutlineOn()
  184. {
  185. return getFontOption(outline);
  186. }
  187. public void setShadow(boolean on)
  188. {
  189. setFontOption(on, shadow);
  190. }
  191. public boolean isShadowOn()
  192. {
  193. return getFontOption(shadow);
  194. }
  195. /**
  196. * set the font to be stricken out or not
  197. *
  198. * @param strike - whether the font is stricken out or not
  199. */
  200. public void setStrikeout(boolean strike)
  201. {
  202. setFontOption(strike, cancellation);
  203. }
  204. /**
  205. * get whether the font is to be stricken out or not
  206. *
  207. * @return strike - whether the font is stricken out or not
  208. * @see #getFontOption(org.apache.poi.util.BitField)
  209. */
  210. public boolean isStruckout()
  211. {
  212. return getFontOption(cancellation);
  213. }
  214. /**
  215. * set the font weight (100-1000dec or 0x64-0x3e8). Default is
  216. * 0x190 for normal and 0x2bc for bold
  217. *
  218. * @param bw - a number between 100-1000 for the fonts "boldness"
  219. */
  220. private void setFontWeight(short pbw)
  221. {
  222. short bw = pbw;
  223. if( bw<100) { bw=100; }
  224. if( bw>1000){ bw=1000; }
  225. setShort(OFFSET_FONT_WEIGHT, bw);
  226. }
  227. /**
  228. * set the font weight to bold (weight=700) or to normal(weight=400) boldness.
  229. *
  230. * @param bold - set font weight to bold if true; to normal otherwise
  231. */
  232. public void setBold(boolean bold)
  233. {
  234. setFontWeight(bold?FONT_WEIGHT_BOLD:FONT_WEIGHT_NORMAL);
  235. }
  236. /**
  237. * get the font weight for this font (100-1000dec or 0x64-0x3e8). Default is
  238. * 0x190 for normal and 0x2bc for bold
  239. *
  240. * @return bw - a number between 100-1000 for the fonts "boldness"
  241. */
  242. public short getFontWeight()
  243. {
  244. return getShort(OFFSET_FONT_WEIGHT);
  245. }
  246. /**
  247. * get whether the font weight is set to bold or not
  248. *
  249. * @return bold - whether the font is bold or not
  250. */
  251. public boolean isBold()
  252. {
  253. return getFontWeight()==FONT_WEIGHT_BOLD;
  254. }
  255. /**
  256. * get the type of super or subscript for the font
  257. *
  258. * @return super or subscript option
  259. * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_NONE
  260. * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUPER
  261. * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUB
  262. */
  263. public short getEscapementType()
  264. {
  265. return getShort(OFFSET_ESCAPEMENT_TYPE);
  266. }
  267. /**
  268. * set the escapement type for the font
  269. *
  270. * @param escapementType super or subscript option
  271. * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_NONE
  272. * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUPER
  273. * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUB
  274. */
  275. public void setEscapementType( short escapementType)
  276. {
  277. setShort(OFFSET_ESCAPEMENT_TYPE, escapementType);
  278. }
  279. /**
  280. * get the type of underlining for the font
  281. *
  282. * @return font underlining type
  283. *
  284. * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_NONE
  285. * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE
  286. * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE
  287. * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE_ACCOUNTING
  288. * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE_ACCOUNTING
  289. */
  290. public short getUnderlineType()
  291. {
  292. return getShort(OFFSET_UNDERLINE_TYPE);
  293. }
  294. /**
  295. * set the type of underlining type for the font
  296. *
  297. * @param underlineType underline option
  298. *
  299. * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_NONE
  300. * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE
  301. * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE
  302. * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE_ACCOUNTING
  303. * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE_ACCOUNTING
  304. */
  305. public void setUnderlineType( short underlineType)
  306. {
  307. setShort(OFFSET_UNDERLINE_TYPE, underlineType);
  308. }
  309. public short getFontColorIndex()
  310. {
  311. return (short)getInt(OFFSET_FONT_COLOR_INDEX);
  312. }
  313. public void setFontColorIndex(short fci )
  314. {
  315. setInt(OFFSET_FONT_COLOR_INDEX,fci);
  316. }
  317. private boolean getOptionFlag(BitField field) {
  318. int optionFlags = getInt(OFFSET_OPTION_FLAGS);
  319. int value = field.getValue(optionFlags);
  320. return value==0? true : false ;
  321. }
  322. private void setOptionFlag(boolean modified, BitField field)
  323. {
  324. int value = modified? 0 : 1;
  325. int optionFlags = getInt(OFFSET_OPTION_FLAGS);
  326. optionFlags = field.setValue(optionFlags, value);
  327. setInt(OFFSET_OPTION_FLAGS, optionFlags);
  328. }
  329. public boolean isFontStyleModified()
  330. {
  331. return getOptionFlag(styleModified);
  332. }
  333. public void setFontStyleModified(boolean modified)
  334. {
  335. setOptionFlag(modified, styleModified);
  336. }
  337. public boolean isFontOutlineModified()
  338. {
  339. return getOptionFlag(outlineModified);
  340. }
  341. public void setFontOutlineModified(boolean modified)
  342. {
  343. setOptionFlag(modified, outlineModified);
  344. }
  345. public boolean isFontShadowModified()
  346. {
  347. return getOptionFlag(shadowModified);
  348. }
  349. public void setFontShadowModified(boolean modified)
  350. {
  351. setOptionFlag(modified, shadowModified);
  352. }
  353. public void setFontCancellationModified(boolean modified)
  354. {
  355. setOptionFlag(modified, cancellationModified);
  356. }
  357. public boolean isFontCancellationModified()
  358. {
  359. return getOptionFlag(cancellationModified);
  360. }
  361. public void setEscapementTypeModified(boolean modified)
  362. {
  363. int value = modified? 0 : 1;
  364. setInt(OFFSET_ESCAPEMENT_TYPE_MODIFIED, value);
  365. }
  366. public boolean isEscapementTypeModified()
  367. {
  368. int escapementModified = getInt(OFFSET_ESCAPEMENT_TYPE_MODIFIED);
  369. return escapementModified == 0;
  370. }
  371. public void setUnderlineTypeModified(boolean modified)
  372. {
  373. int value = modified? 0 : 1;
  374. setInt(OFFSET_UNDERLINE_TYPE_MODIFIED, value);
  375. }
  376. public boolean isUnderlineTypeModified()
  377. {
  378. int underlineModified = getInt(OFFSET_UNDERLINE_TYPE_MODIFIED);
  379. return underlineModified == 0;
  380. }
  381. public void setFontWieghtModified(boolean modified)
  382. {
  383. int value = modified? 0 : 1;
  384. setInt(OFFSET_FONT_WEIGHT_MODIFIED, value);
  385. }
  386. public boolean isFontWeightModified()
  387. {
  388. int fontStyleModified = getInt(OFFSET_FONT_WEIGHT_MODIFIED);
  389. return fontStyleModified == 0;
  390. }
  391. public String toString()
  392. {
  393. StringBuffer buffer = new StringBuffer();
  394. buffer.append(" [Font Formatting]\n");
  395. buffer.append(" .font height = ").append(getFontHeight()).append(" twips\n");
  396. if( isFontStyleModified() )
  397. {
  398. buffer.append(" .font posture = ").append(isItalic()?"Italic":"Normal").append("\n");
  399. }
  400. else
  401. {
  402. buffer.append(" .font posture = ]not modified]").append("\n");
  403. }
  404. if( isFontOutlineModified() )
  405. {
  406. buffer.append(" .font outline = ").append(isOutlineOn()).append("\n");
  407. }
  408. else
  409. {
  410. buffer.append(" .font outline is not modified\n");
  411. }
  412. if( isFontShadowModified() )
  413. {
  414. buffer.append(" .font shadow = ").append(isShadowOn()).append("\n");
  415. }
  416. else
  417. {
  418. buffer.append(" .font shadow is not modified\n");
  419. }
  420. if( isFontCancellationModified() )
  421. {
  422. buffer.append(" .font strikeout = ").append(isStruckout()).append("\n");
  423. }
  424. else
  425. {
  426. buffer.append(" .font strikeout is not modified\n");
  427. }
  428. if( isFontStyleModified() )
  429. {
  430. buffer.append(" .font weight = ").
  431. append(getFontWeight()).
  432. append(
  433. getFontWeight() == FONT_WEIGHT_NORMAL ? "(Normal)"
  434. : getFontWeight() == FONT_WEIGHT_BOLD ? "(Bold)"
  435. : "0x"+Integer.toHexString(getFontWeight())).
  436. append("\n");
  437. }
  438. else
  439. {
  440. buffer.append(" .font weight = ]not modified]").append("\n");
  441. }
  442. if( isEscapementTypeModified() )
  443. {
  444. buffer.append(" .escapement type = ").append(getEscapementType()).append("\n");
  445. }
  446. else
  447. {
  448. buffer.append(" .escapement type is not modified\n");
  449. }
  450. if( isUnderlineTypeModified() )
  451. {
  452. buffer.append(" .underline type = ").append(getUnderlineType()).append("\n");
  453. }
  454. else
  455. {
  456. buffer.append(" .underline type is not modified\n");
  457. }
  458. buffer.append(" .color index = ").append("0x"+Integer.toHexString(getFontColorIndex()).toUpperCase()).append("\n");
  459. buffer.append(" [/Font Formatting]\n");
  460. return buffer.toString();
  461. }
  462. public Object clone()
  463. {
  464. byte[] rawData = _rawData.clone();
  465. return new FontFormatting(rawData);
  466. }
  467. }