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.

OldFfn.java 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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.hwpf.model;
  16. import java.nio.charset.Charset;
  17. import org.apache.poi.hwmf.record.HwmfFont;
  18. import org.apache.poi.util.Internal;
  19. import org.apache.poi.util.LittleEndian;
  20. import org.apache.poi.util.POILogFactory;
  21. import org.apache.poi.util.POILogger;
  22. import org.apache.poi.util.StringUtil;
  23. /**
  24. * Word 6.0 Font information
  25. */
  26. @Internal
  27. public final class OldFfn {
  28. private static final POILogger logger = POILogFactory.getLogger(OldFfn.class);
  29. private byte _chs;// character set identifier
  30. private final String fontName;
  31. private final String altFontName;
  32. private final int length; //length in bytes for this record
  33. /**
  34. * try to read an OldFfn starting at offset; read no farther than end
  35. *
  36. * @param buf buffer from which to read
  37. * @param offset offset at which to start
  38. * @param fontTableEnd read no farther than this
  39. * @return an OldFfn or null if asked to read beyond end
  40. */
  41. static OldFfn build(byte[] buf, int offset, int fontTableEnd) {
  42. int start = offset;
  43. //preliminary bytes
  44. if (offset + 6 > fontTableEnd) {
  45. return null;
  46. }
  47. //first byte
  48. short fontDescriptionLength = (short) buf[offset];
  49. offset += 1;
  50. if (offset + fontDescriptionLength > fontTableEnd) {
  51. logger.log(POILogger.WARN, "Asked to read beyond font table end. Skipping font");
  52. return null;
  53. }
  54. //no idea what these 3 bytes do
  55. offset += 3;
  56. byte chs = buf[offset];
  57. Charset charset = null;
  58. HwmfFont.WmfCharset wmfCharset = HwmfFont.WmfCharset.valueOf(chs & 0xff);
  59. if (wmfCharset == null) {
  60. logger.log(POILogger.WARN, "Couldn't find font for type: " + (chs & 0xff));
  61. } else {
  62. charset = wmfCharset.getCharset();
  63. }
  64. charset = charset == null ? StringUtil.WIN_1252 : charset;
  65. offset += LittleEndian.BYTE_SIZE;
  66. //if this byte here == 7, it _may_ signify existence of
  67. //an altername font name
  68. //not sure what the byte after the _chs does
  69. offset += LittleEndian.BYTE_SIZE;
  70. int fontNameLength = -1;
  71. for (int i = offset; i < fontTableEnd; i++) {
  72. if (buf[i] == 0) {
  73. fontNameLength = i - offset;
  74. break;
  75. }
  76. }
  77. if (fontNameLength == -1) {
  78. logger.log(POILogger.WARN, "Couldn't find the zero-byte delimited font name length");
  79. return null;
  80. }
  81. String fontName = new String(buf, offset, fontNameLength, charset);
  82. String altFontName = null;
  83. int altFontNameLength = -1;
  84. offset += fontNameLength + 1;
  85. if (offset - start < fontDescriptionLength) {
  86. for (int i = offset; i <= start + fontDescriptionLength; i++) {
  87. if (buf[i] == 0) {
  88. altFontNameLength = i - offset;
  89. break;
  90. }
  91. }
  92. if (altFontNameLength > -1) {
  93. altFontName = new String(buf, offset, altFontNameLength, charset);
  94. }
  95. }
  96. //reset to 0 for length calculation
  97. altFontNameLength = (altFontNameLength < 0) ? 0 : altFontNameLength + 1;//add one for zero byte
  98. int len = LittleEndian.INT_SIZE + LittleEndian.BYTE_SIZE + LittleEndian.BYTE_SIZE +//6 starting bytes
  99. fontNameLength + altFontNameLength + 1;//+1 is for the zero byte
  100. //this len should == fontDescriptionLength
  101. return new OldFfn(chs, fontName, altFontName, len);
  102. }
  103. public OldFfn(byte charsetIdentifier, String fontName, String altFontName, int length) {
  104. this._chs = charsetIdentifier;
  105. this.fontName = fontName;
  106. this.altFontName = altFontName;
  107. this.length = length;
  108. }
  109. public byte getChs() {
  110. return _chs;
  111. }
  112. public String getMainFontName() {
  113. return fontName;
  114. }
  115. /**
  116. * @return altFontName if it exists, null otherwise
  117. */
  118. public String getAltFontName() {
  119. return altFontName;
  120. }
  121. /**
  122. * @return length in bytes for this record
  123. */
  124. public int getLength() {
  125. return length;
  126. }
  127. @Override
  128. public String toString() {
  129. return "OldFfn{" +
  130. "_chs=" + (_chs & 0xff) +
  131. ", fontName='" + fontName + '\'' +
  132. ", altFontName='" + altFontName + '\'' +
  133. ", length=" + length +
  134. '}';
  135. }
  136. }