0001: /* ====================================================================
0002: Licensed to the Apache Software Foundation (ASF) under one or more
0003: contributor license agreements. See the NOTICE file distributed with
0004: this work for additional information regarding copyright ownership.
0005: The ASF licenses this file to You under the Apache License, Version 2.0
0006: (the "License"); you may not use this file except in compliance with
0007: the License. You may obtain a copy of the License at
0008:
0009: http://www.apache.org/licenses/LICENSE-2.0
0010:
0011: Unless required by applicable law or agreed to in writing, software
0012: distributed under the License is distributed on an "AS IS" BASIS,
0013: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: See the License for the specific language governing permissions and
0015: limitations under the License.
0016: ==================================================================== */
0017:
0018: package org.apache.poi.hdf.model.hdftypes;
0019:
0020: import java.util.*;
0021: import org.apache.poi.util.LittleEndian;
0022: import org.apache.poi.hdf.model.hdftypes.definitions.TCAbstractType;
0023:
0024: /**
0025: * Represents a document's stylesheet. A word documents formatting is stored as
0026: * compressed styles that are based on styles contained in the stylesheet. This
0027: * class also contains static utility functions to uncompress different
0028: * formatting properties.
0029: *
0030: * @author Ryan Ackley
0031: */
0032:
0033: public class StyleSheet implements HDFType {
0034:
0035: private static final int NIL_STYLE = 4095;
0036: private static final int PAP_TYPE = 1;
0037: private static final int CHP_TYPE = 2;
0038: private static final int SEP_TYPE = 4;
0039: private static final int TAP_TYPE = 5;
0040: //Vector _styleDescriptions;
0041: StyleDescription _nilStyle = new StyleDescription();
0042: StyleDescription[] _styleDescriptions;
0043:
0044: /**
0045: * StyleSheet constructor. Loads a document's stylesheet information,
0046: *
0047: * @param styleSheet A byte array containing a document's raw stylesheet
0048: * info. Found by using FileInformationBlock.getFcStshf() and
0049: * FileInformationBLock.getLcbStshf()
0050: */
0051: public StyleSheet(byte[] styleSheet) {
0052: int stshiLength = LittleEndian.getShort(styleSheet, 0);
0053: int stdCount = LittleEndian.getShort(styleSheet, 2);
0054: int baseLength = LittleEndian.getShort(styleSheet, 4);
0055: int[] rgftc = new int[3];
0056:
0057: rgftc[0] = LittleEndian.getInt(styleSheet, 14);
0058: rgftc[1] = LittleEndian.getInt(styleSheet, 18);
0059: rgftc[2] = LittleEndian.getInt(styleSheet, 22);
0060:
0061: int offset = 0;
0062: _styleDescriptions = new StyleDescription[stdCount];
0063: for (int x = 0; x < stdCount; x++) {
0064: int stdOffset = (2 + stshiLength) + offset;
0065: int stdSize = LittleEndian.getShort(styleSheet, stdOffset);
0066: if (stdSize > 0) {
0067: byte[] std = new byte[stdSize];
0068:
0069: //get past the size
0070: stdOffset += 2;
0071: System
0072: .arraycopy(styleSheet, stdOffset, std, 0,
0073: stdSize);
0074: StyleDescription aStyle = new StyleDescription(std,
0075: baseLength, true);
0076:
0077: _styleDescriptions[x] = aStyle;
0078: }
0079:
0080: offset += stdSize + 2;
0081:
0082: }
0083: for (int x = 0; x < _styleDescriptions.length; x++) {
0084: if (_styleDescriptions[x] != null) {
0085: createPap(x);
0086: createChp(x);
0087: }
0088: }
0089: }
0090:
0091: /**
0092: * Creates a PartagraphProperties object from a papx stored in the
0093: * StyleDescription at the index istd in the StyleDescription array. The PAP
0094: * is placed in the StyleDescription at istd after its been created. Not
0095: * every StyleDescription will contain a papx. In these cases this function
0096: * does nothing
0097: *
0098: * @param istd The index of the StyleDescription to create the
0099: * ParagraphProperties from (and also place the finished PAP in)
0100: */
0101: private void createPap(int istd) {
0102: StyleDescription sd = _styleDescriptions[istd];
0103: ParagraphProperties pap = sd.getPAP();
0104: byte[] papx = sd.getPAPX();
0105: int baseIndex = sd.getBaseStyle();
0106: if (pap == null && papx != null) {
0107: ParagraphProperties parentPAP = _nilStyle.getPAP();
0108: if (baseIndex != NIL_STYLE) {
0109:
0110: parentPAP = _styleDescriptions[baseIndex].getPAP();
0111: if (parentPAP == null) {
0112: createPap(baseIndex);
0113: parentPAP = _styleDescriptions[baseIndex].getPAP();
0114: }
0115:
0116: }
0117:
0118: pap = (ParagraphProperties) uncompressProperty(papx,
0119: parentPAP, this );
0120: sd.setPAP(pap);
0121: }
0122: }
0123:
0124: /**
0125: * Creates a CharacterProperties object from a chpx stored in the
0126: * StyleDescription at the index istd in the StyleDescription array. The
0127: * CharacterProperties object is placed in the StyleDescription at istd after
0128: * its been created. Not every StyleDescription will contain a chpx. In these
0129: * cases this function does nothing.
0130: *
0131: * @param istd The index of the StyleDescription to create the
0132: * CharacterProperties object from.
0133: */
0134: private void createChp(int istd) {
0135: StyleDescription sd = _styleDescriptions[istd];
0136: CharacterProperties chp = sd.getCHP();
0137: byte[] chpx = sd.getCHPX();
0138: int baseIndex = sd.getBaseStyle();
0139: if (chp == null && chpx != null) {
0140: CharacterProperties parentCHP = _nilStyle.getCHP();
0141: if (baseIndex != NIL_STYLE) {
0142:
0143: parentCHP = _styleDescriptions[baseIndex].getCHP();
0144: if (parentCHP == null) {
0145: createChp(baseIndex);
0146: parentCHP = _styleDescriptions[baseIndex].getCHP();
0147: }
0148:
0149: }
0150:
0151: chp = (CharacterProperties) uncompressProperty(chpx,
0152: parentCHP, this );
0153: sd.setCHP(chp);
0154: }
0155: }
0156:
0157: /**
0158: * Gets the StyleDescription at index x.
0159: *
0160: * @param x the index of the desired StyleDescription.
0161: */
0162: public StyleDescription getStyleDescription(int x) {
0163: return _styleDescriptions[x];
0164: }
0165:
0166: /**
0167: * Used in decompression of a chpx. This performs an operation defined by
0168: * a single sprm.
0169: *
0170: * @param oldCHP The base CharacterProperties.
0171: * @param newCHP The current CharacterProperties.
0172: * @param operand The operand defined by the sprm (See Word file format spec)
0173: * @param param The parameter defined by the sprm (See Word file format spec)
0174: * @param varParam The variable length parameter defined by the sprm. (See
0175: * Word file format spec)
0176: * @param grpprl The entire chpx that this operation is a part of.
0177: * @param offset The offset in the grpprl of the next sprm
0178: * @param styleSheet The StyleSheet for this document.
0179: */
0180: static void doCHPOperation(CharacterProperties oldCHP,
0181: CharacterProperties newCHP, int operand, int param,
0182: byte[] varParam, byte[] grpprl, int offset,
0183: StyleSheet styleSheet) {
0184: switch (operand) {
0185: case 0:
0186: newCHP.setFRMarkDel(getFlag(param));
0187: break;
0188: case 0x1:
0189: newCHP.setFRMark(getFlag(param));
0190: break;
0191: case 0x2:
0192: break;
0193: case 0x3:
0194: newCHP.setFcPic(param);
0195: newCHP.setFSpec(true);
0196: break;
0197: case 0x4:
0198: newCHP.setIbstRMark((short) param);
0199: break;
0200: case 0x5:
0201: short[] dttmRMark = new short[2];
0202: dttmRMark[0] = LittleEndian.getShort(grpprl, (offset - 4));
0203: dttmRMark[1] = LittleEndian.getShort(grpprl, (offset - 2));
0204: newCHP.setDttmRMark(dttmRMark);
0205: break;
0206: case 0x6:
0207: newCHP.setFData(getFlag(param));
0208: break;
0209: case 0x7:
0210: //don't care about this
0211: break;
0212: case 0x8:
0213: short chsDiff = (short) ((param & 0xff0000) >>> 8);
0214: newCHP.setFChsDiff(getFlag(chsDiff));
0215: newCHP.setChse((short) (param & 0xffff));
0216: break;
0217: case 0x9:
0218: newCHP.setFSpec(true);
0219: newCHP
0220: .setFtcSym((short) LittleEndian.getShort(varParam,
0221: 0));
0222: newCHP
0223: .setXchSym((short) LittleEndian.getShort(varParam,
0224: 2));
0225: break;
0226: case 0xa:
0227: newCHP.setFOle2(getFlag(param));
0228: break;
0229: case 0xb:
0230: //?
0231: break;
0232: case 0xc:
0233: newCHP.setIcoHighlight((byte) param);
0234: newCHP.setFHighlight(getFlag(param));
0235: break;
0236: case 0xd:
0237: break;
0238: case 0xe:
0239: newCHP.setFcObj(param);
0240: break;
0241: case 0xf:
0242: break;
0243: case 0x10:
0244: //?
0245: break;
0246: case 0x11:
0247: break;
0248: case 0x12:
0249: break;
0250: case 0x13:
0251: break;
0252: case 0x14:
0253: break;
0254: case 0x15:
0255: break;
0256: case 0x16:
0257: break;
0258: case 0x17:
0259: break;
0260: case 0x18:
0261: break;
0262: case 0x19:
0263: break;
0264: case 0x1a:
0265: break;
0266: case 0x1b:
0267: break;
0268: case 0x1c:
0269: break;
0270: case 0x1d:
0271: break;
0272: case 0x1e:
0273: break;
0274: case 0x1f:
0275: break;
0276: case 0x20:
0277: break;
0278: case 0x21:
0279: break;
0280: case 0x22:
0281: break;
0282: case 0x23:
0283: break;
0284: case 0x24:
0285: break;
0286: case 0x25:
0287: break;
0288: case 0x26:
0289: break;
0290: case 0x27:
0291: break;
0292: case 0x28:
0293: break;
0294: case 0x29:
0295: break;
0296: case 0x2a:
0297: break;
0298: case 0x2b:
0299: break;
0300: case 0x2c:
0301: break;
0302: case 0x2d:
0303: break;
0304: case 0x2e:
0305: break;
0306: case 0x2f:
0307: break;
0308: case 0x30:
0309: newCHP.setIstd(param);
0310: break;
0311: case 0x31:
0312: //permutation vector for fast saves, who cares!
0313: break;
0314: case 0x32:
0315: newCHP.setFBold(false);
0316: newCHP.setFItalic(false);
0317: newCHP.setFOutline(false);
0318: newCHP.setFStrike(false);
0319: newCHP.setFShadow(false);
0320: newCHP.setFSmallCaps(false);
0321: newCHP.setFCaps(false);
0322: newCHP.setFVanish(false);
0323: newCHP.setKul((byte) 0);
0324: newCHP.setIco((byte) 0);
0325: break;
0326: case 0x33:
0327: try {
0328: newCHP = (CharacterProperties) oldCHP.clone();
0329: } catch (CloneNotSupportedException e) {
0330: //do nothing
0331: }
0332: return;
0333: case 0x34:
0334: break;
0335: case 0x35:
0336: newCHP.setFBold(getCHPFlag((byte) param, oldCHP.isFBold()));
0337: break;
0338: case 0x36:
0339: newCHP.setFItalic(getCHPFlag((byte) param, oldCHP
0340: .isFItalic()));
0341: break;
0342: case 0x37:
0343: newCHP.setFStrike(getCHPFlag((byte) param, oldCHP
0344: .isFStrike()));
0345: break;
0346: case 0x38:
0347: newCHP.setFOutline(getCHPFlag((byte) param, oldCHP
0348: .isFOutline()));
0349: break;
0350: case 0x39:
0351: newCHP.setFShadow(getCHPFlag((byte) param, oldCHP
0352: .isFShadow()));
0353: break;
0354: case 0x3a:
0355: newCHP.setFSmallCaps(getCHPFlag((byte) param, oldCHP
0356: .isFSmallCaps()));
0357: break;
0358: case 0x3b:
0359: newCHP.setFCaps(getCHPFlag((byte) param, oldCHP.isFCaps()));
0360: break;
0361: case 0x3c:
0362: newCHP.setFVanish(getCHPFlag((byte) param, oldCHP
0363: .isFVanish()));
0364: break;
0365: case 0x3d:
0366: newCHP.setFtcAscii((short) param);
0367: break;
0368: case 0x3e:
0369: newCHP.setKul((byte) param);
0370: break;
0371: case 0x3f:
0372: int hps = param & 0xff;
0373: if (hps != 0) {
0374: newCHP.setHps(hps);
0375: }
0376: byte cInc = (byte) (((byte) (param & 0xfe00) >>> 4) >> 1);
0377: if (cInc != 0) {
0378: newCHP
0379: .setHps(Math.max(newCHP.getHps() + (cInc * 2),
0380: 2));
0381: }
0382: byte hpsPos = (byte) ((param & 0xff0000) >>> 8);
0383: if (hpsPos != 0x80) {
0384: newCHP.setHpsPos(hpsPos);
0385: }
0386: boolean fAdjust = (param & 0x0100) > 0;
0387: if (fAdjust && hpsPos != 128 && hpsPos != 0
0388: && oldCHP.getHpsPos() == 0) {
0389: newCHP.setHps(Math.max(newCHP.getHps() + (-2), 2));
0390: }
0391: if (fAdjust && hpsPos == 0 && oldCHP.getHpsPos() != 0) {
0392: newCHP.setHps(Math.max(newCHP.getHps() + 2, 2));
0393: }
0394: break;
0395: case 0x40:
0396: newCHP.setDxaSpace(param);
0397: break;
0398: case 0x41:
0399: newCHP.setLidDefault((short) param);
0400: break;
0401: case 0x42:
0402: newCHP.setIco((byte) param);
0403: break;
0404: case 0x43:
0405: newCHP.setHps(param);
0406: break;
0407: case 0x44:
0408: byte hpsLvl = (byte) param;
0409: newCHP.setHps(Math.max(newCHP.getHps() + (hpsLvl * 2), 2));
0410: break;
0411: case 0x45:
0412: newCHP.setHpsPos((short) param);
0413: break;
0414: case 0x46:
0415: if (param != 0) {
0416: if (oldCHP.getHpsPos() == 0) {
0417: newCHP.setHps(Math.max(newCHP.getHps() + (-2), 2));
0418: }
0419: } else {
0420: if (oldCHP.getHpsPos() != 0) {
0421: newCHP.setHps(Math.max(newCHP.getHps() + 2, 2));
0422: }
0423: }
0424: break;
0425: case 0x47:
0426: CharacterProperties genCHP = new CharacterProperties();
0427: genCHP.setFtcAscii(4);
0428: genCHP = (CharacterProperties) uncompressProperty(varParam,
0429: genCHP, styleSheet);
0430: CharacterProperties styleCHP = styleSheet
0431: .getStyleDescription(oldCHP.getBaseIstd()).getCHP();
0432: if (genCHP.isFBold() == newCHP.isFBold()) {
0433: newCHP.setFBold(styleCHP.isFBold());
0434: }
0435: if (genCHP.isFItalic() == newCHP.isFItalic()) {
0436: newCHP.setFItalic(styleCHP.isFItalic());
0437: }
0438: if (genCHP.isFSmallCaps() == newCHP.isFSmallCaps()) {
0439: newCHP.setFSmallCaps(styleCHP.isFSmallCaps());
0440: }
0441: if (genCHP.isFVanish() == newCHP.isFVanish()) {
0442: newCHP.setFVanish(styleCHP.isFVanish());
0443: }
0444: if (genCHP.isFStrike() == newCHP.isFStrike()) {
0445: newCHP.setFStrike(styleCHP.isFStrike());
0446: }
0447: if (genCHP.isFCaps() == newCHP.isFCaps()) {
0448: newCHP.setFCaps(styleCHP.isFCaps());
0449: }
0450: if (genCHP.getFtcAscii() == newCHP.getFtcAscii()) {
0451: newCHP.setFtcAscii(styleCHP.getFtcAscii());
0452: }
0453: if (genCHP.getFtcFE() == newCHP.getFtcFE()) {
0454: newCHP.setFtcFE(styleCHP.getFtcFE());
0455: }
0456: if (genCHP.getFtcOther() == newCHP.getFtcOther()) {
0457: newCHP.setFtcOther(styleCHP.getFtcOther());
0458: }
0459: if (genCHP.getHps() == newCHP.getHps()) {
0460: newCHP.setHps(styleCHP.getHps());
0461: }
0462: if (genCHP.getHpsPos() == newCHP.getHpsPos()) {
0463: newCHP.setHpsPos(styleCHP.getHpsPos());
0464: }
0465: if (genCHP.getKul() == newCHP.getKul()) {
0466: newCHP.setKul(styleCHP.getKul());
0467: }
0468: if (genCHP.getDxaSpace() == newCHP.getDxaSpace()) {
0469: newCHP.setDxaSpace(styleCHP.getDxaSpace());
0470: }
0471: if (genCHP.getIco() == newCHP.getIco()) {
0472: newCHP.setIco(styleCHP.getIco());
0473: }
0474: if (genCHP.getLidDefault() == newCHP.getLidDefault()) {
0475: newCHP.setLidDefault(styleCHP.getLidDefault());
0476: }
0477: if (genCHP.getLidFE() == newCHP.getLidFE()) {
0478: newCHP.setLidFE(styleCHP.getLidFE());
0479: }
0480: break;
0481: case 0x48:
0482: newCHP.setIss((byte) param);
0483: break;
0484: case 0x49:
0485: newCHP.setHps(LittleEndian.getShort(varParam, 0));
0486: break;
0487: case 0x4a:
0488: int increment = LittleEndian.getShort(varParam, 0);
0489: newCHP.setHps(Math.max(newCHP.getHps() + increment, 8));
0490: break;
0491: case 0x4b:
0492: newCHP.setHpsKern(param);
0493: break;
0494: case 0x4c:
0495: doCHPOperation(oldCHP, newCHP, 0x47, param, varParam,
0496: grpprl, offset, styleSheet);
0497: break;
0498: case 0x4d:
0499: float percentage = (float) param / 100.0f;
0500: int add = (int) ((float) percentage * (float) newCHP
0501: .getHps());
0502: newCHP.setHps(newCHP.getHps() + add);
0503: break;
0504: case 0x4e:
0505: newCHP.setYsr((byte) param);
0506: break;
0507: case 0x4f:
0508: newCHP.setFtcAscii((short) param);
0509: break;
0510: case 0x50:
0511: newCHP.setFtcFE((short) param);
0512: break;
0513: case 0x51:
0514: newCHP.setFtcOther((short) param);
0515: break;
0516: case 0x52:
0517: break;
0518: case 0x53:
0519: newCHP.setFDStrike(getFlag(param));
0520: break;
0521: case 0x54:
0522: newCHP.setFImprint(getFlag(param));
0523: break;
0524: case 0x55:
0525: newCHP.setFSpec(getFlag(param));
0526: break;
0527: case 0x56:
0528: newCHP.setFObj(getFlag(param));
0529: break;
0530: case 0x57:
0531: newCHP.setFPropMark(varParam[0]);
0532: newCHP.setIbstPropRMark((short) LittleEndian.getShort(
0533: varParam, 1));
0534: newCHP.setDttmPropRMark(LittleEndian.getInt(varParam, 3));
0535: break;
0536: case 0x58:
0537: newCHP.setFEmboss(getFlag(param));
0538: break;
0539: case 0x59:
0540: newCHP.setSfxtText((byte) param);
0541: break;
0542: case 0x5a:
0543: break;
0544: case 0x5b:
0545: break;
0546: case 0x5c:
0547: break;
0548: case 0x5d:
0549: break;
0550: case 0x5e:
0551: break;
0552: case 0x5f:
0553: break;
0554: case 0x60:
0555: break;
0556: case 0x61:
0557: break;
0558: case 0x62:
0559: byte[] xstDispFldRMark = new byte[32];
0560: newCHP.setFDispFldRMark(varParam[0]);
0561: newCHP.setIbstDispFldRMark((short) LittleEndian.getShort(
0562: varParam, 1));
0563: newCHP
0564: .setDttmDispFldRMark(LittleEndian.getInt(varParam,
0565: 3));
0566: System.arraycopy(varParam, 7, xstDispFldRMark, 0, 32);
0567: newCHP.setXstDispFldRMark(xstDispFldRMark);
0568: break;
0569: case 0x63:
0570: newCHP.setIbstRMarkDel((short) param);
0571: break;
0572: case 0x64:
0573: short[] dttmRMarkDel = new short[2];
0574: dttmRMarkDel[0] = LittleEndian.getShort(grpprl, offset - 4);
0575: dttmRMarkDel[1] = LittleEndian.getShort(grpprl, offset - 2);
0576: newCHP.setDttmRMarkDel(dttmRMarkDel);
0577: break;
0578: case 0x65:
0579: short[] brc = new short[2];
0580: brc[0] = (short) LittleEndian.getShort(grpprl, offset - 4);
0581: brc[1] = (short) LittleEndian.getShort(grpprl, offset - 2);
0582: newCHP.setBrc(brc);
0583: break;
0584: case 0x66:
0585: newCHP.setShd((short) param);
0586: break;
0587: case 0x67:
0588: break;
0589: case 0x68:
0590: break;
0591: case 0x69:
0592: break;
0593: case 0x6a:
0594: break;
0595: case 0x6b:
0596: break;
0597: case 0x6c:
0598: break;
0599: case 0x6d:
0600: newCHP.setLidDefault((short) param);
0601: break;
0602: case 0x6e:
0603: newCHP.setLidFE((short) param);
0604: break;
0605: case 0x6f:
0606: newCHP.setIdctHint((byte) param);
0607: break;
0608: }
0609: }
0610:
0611: /**
0612: * Used to uncompress a property stored in a grpprl. These include
0613: * CharacterProperties, ParagraphProperties, TableProperties, and
0614: * SectionProperties.
0615: *
0616: * @param grpprl The compressed form of the property.
0617: * @param parent The base property of the property.
0618: * @param styleSheet The document's stylesheet.
0619: *
0620: * @return An object that should be casted to the appropriate property.
0621: */
0622: public static Object uncompressProperty(byte[] grpprl,
0623: Object parent, StyleSheet styleSheet) {
0624: return uncompressProperty(grpprl, parent, styleSheet, true);
0625: }
0626:
0627: /**
0628: * Used to uncompress a property stored in a grpprl. These include
0629: * CharacterProperties, ParagraphProperties, TableProperties, and
0630: * SectionProperties.
0631: *
0632: * @param grpprl The compressed form of the property.
0633: * @param parent The base property of the property.
0634: * @param styleSheet The document's stylesheet.
0635: *
0636: * @return An object that should be casted to the appropriate property.
0637: */
0638: public static Object uncompressProperty(byte[] grpprl,
0639: Object parent, StyleSheet styleSheet, boolean doIstd) {
0640: Object newProperty = null;
0641: int offset = 0;
0642: int propertyType = PAP_TYPE;
0643:
0644: if (parent instanceof ParagraphProperties) {
0645: try {
0646: newProperty = ((ParagraphProperties) parent).clone();
0647: } catch (Exception e) {
0648: }
0649: if (doIstd) {
0650: ((ParagraphProperties) newProperty)
0651: .setIstd(LittleEndian.getShort(grpprl, 0));
0652:
0653: offset = 2;
0654: }
0655: } else if (parent instanceof CharacterProperties) {
0656: try {
0657: newProperty = ((CharacterProperties) parent).clone();
0658: ((CharacterProperties) newProperty)
0659: .setBaseIstd(((CharacterProperties) parent)
0660: .getIstd());
0661: } catch (Exception e) {
0662: }
0663: propertyType = CHP_TYPE;
0664: } else if (parent instanceof SectionProperties) {
0665: newProperty = parent;
0666: propertyType = SEP_TYPE;
0667: } else if (parent instanceof TableProperties) {
0668: newProperty = parent;
0669: propertyType = TAP_TYPE;
0670: offset = 2;//because this is really just a papx
0671: } else {
0672: return null;
0673: }
0674:
0675: while (offset < grpprl.length) {
0676: short sprm = LittleEndian.getShort(grpprl, offset);
0677: offset += 2;
0678:
0679: byte spra = (byte) ((sprm & 0xe000) >> 13);
0680: int opSize = 0;
0681: int param = 0;
0682: byte[] varParam = null;
0683:
0684: switch (spra) {
0685: case 0:
0686: case 1:
0687: opSize = 1;
0688: param = grpprl[offset];
0689: break;
0690: case 2:
0691: opSize = 2;
0692: param = LittleEndian.getShort(grpprl, offset);
0693: break;
0694: case 3:
0695: opSize = 4;
0696: param = LittleEndian.getInt(grpprl, offset);
0697: break;
0698: case 4:
0699: case 5:
0700: opSize = 2;
0701: param = LittleEndian.getShort(grpprl, offset);
0702: break;
0703: case 6://variable size
0704:
0705: //there is one sprm that is a very special case
0706: if (sprm != (short) 0xd608) {
0707: opSize = LittleEndian.getUnsignedByte(grpprl,
0708: offset);
0709: offset++;
0710: } else {
0711: opSize = LittleEndian.getShort(grpprl, offset) - 1;
0712: offset += 2;
0713: }
0714: varParam = new byte[opSize];
0715: System.arraycopy(grpprl, offset, varParam, 0, opSize);
0716:
0717: break;
0718: case 7:
0719: opSize = 3;
0720: byte threeByteInt[] = new byte[4];
0721: threeByteInt[0] = grpprl[offset];
0722: threeByteInt[1] = grpprl[offset + 1];
0723: threeByteInt[2] = grpprl[offset + 2];
0724: threeByteInt[3] = (byte) 0;
0725: param = LittleEndian.getInt(threeByteInt, 0);
0726: break;
0727: default:
0728: throw new RuntimeException("unrecognized pap opcode");
0729: }
0730:
0731: offset += opSize;
0732: short operand = (short) (sprm & 0x1ff);
0733: byte type = (byte) ((sprm & 0x1c00) >> 10);
0734: switch (propertyType) {
0735: case PAP_TYPE:
0736: if (type == 1)//papx stores TAP sprms along with PAP sprms
0737: {
0738: doPAPOperation((ParagraphProperties) newProperty,
0739: operand, param, varParam, grpprl, offset,
0740: spra);
0741: }
0742: break;
0743: case CHP_TYPE:
0744:
0745: doCHPOperation((CharacterProperties) parent,
0746: (CharacterProperties) newProperty, operand,
0747: param, varParam, grpprl, offset, styleSheet);
0748: break;
0749: case SEP_TYPE:
0750:
0751: doSEPOperation((SectionProperties) newProperty,
0752: operand, param, varParam);
0753: break;
0754: case TAP_TYPE:
0755: if (type == 5) {
0756: doTAPOperation((TableProperties) newProperty,
0757: operand, param, varParam);
0758: }
0759: break;
0760: }
0761:
0762: }
0763: return newProperty;
0764:
0765: }
0766:
0767: /**
0768: * Performs an operation on a ParagraphProperties object. Used to uncompress
0769: * from a papx.
0770: *
0771: * @param newPAP The ParagraphProperties object to perform the operation on.
0772: * @param operand The operand that defines the operation.
0773: * @param param The operation's parameter.
0774: * @param varParam The operation's variable length parameter.
0775: * @param grpprl The original papx.
0776: * @param offset The current offset in the papx.
0777: * @param spra A part of the sprm that defined this operation.
0778: */
0779: static void doPAPOperation(ParagraphProperties newPAP, int operand,
0780: int param, byte[] varParam, byte[] grpprl, int offset,
0781: int spra) {
0782: switch (operand) {
0783: case 0:
0784: newPAP.setIstd(param);
0785: break;
0786: case 0x1:
0787: //permuteIstd(newPAP, varParam);
0788: break;
0789: case 0x2:
0790: if (newPAP.getIstd() <= 9 || newPAP.getIstd() >= 1) {
0791: newPAP.setIstd(newPAP.getIstd() + param);
0792: if (param > 0) {
0793: newPAP.setIstd(Math.max(newPAP.getIstd(), 9));
0794: } else {
0795: newPAP.setIstd(Math.min(newPAP.getIstd(), 1));
0796: }
0797: }
0798: break;
0799: case 0x3:
0800: newPAP.setJc((byte) param);
0801: break;
0802: case 0x4:
0803: newPAP.setFSideBySide((byte) param);
0804: break;
0805: case 0x5:
0806: newPAP.setFKeep((byte) param);
0807: break;
0808: case 0x6:
0809: newPAP.setFKeepFollow((byte) param);
0810: break;
0811: case 0x7:
0812: newPAP.setFPageBreakBefore((byte) param);
0813: break;
0814: case 0x8:
0815: newPAP.setBrcl((byte) param);
0816: break;
0817: case 0x9:
0818: newPAP.setBrcp((byte) param);
0819: break;
0820: case 0xa:
0821: newPAP.setIlvl((byte) param);
0822: break;
0823: case 0xb:
0824: newPAP.setIlfo(param);
0825: break;
0826: case 0xc:
0827: newPAP.setFNoLnn((byte) param);
0828: break;
0829: case 0xd:
0830: /**@todo handle tabs*/
0831: break;
0832: case 0xe:
0833: newPAP.setDxaRight(param);
0834: break;
0835: case 0xf:
0836: newPAP.setDxaLeft(param);
0837: break;
0838: case 0x10:
0839: newPAP.setDxaLeft(newPAP.getDxaLeft() + param);
0840: newPAP.setDxaLeft(Math.max(0, newPAP.getDxaLeft()));
0841: break;
0842: case 0x11:
0843: newPAP.setDxaLeft1(param);
0844: break;
0845: case 0x12:
0846: short[] lspd = newPAP.getLspd();
0847: lspd[0] = LittleEndian.getShort(grpprl, offset - 4);
0848: lspd[1] = LittleEndian.getShort(grpprl, offset - 2);
0849: break;
0850: case 0x13:
0851: newPAP.setDyaBefore(param);
0852: break;
0853: case 0x14:
0854: newPAP.setDyaAfter(param);
0855: break;
0856: case 0x15:
0857: /**@todo handle tabs*/
0858: break;
0859: case 0x16:
0860: newPAP.setFInTable((byte) param);
0861: break;
0862: case 0x17:
0863: newPAP.setFTtp((byte) param);
0864: break;
0865: case 0x18:
0866: newPAP.setDxaAbs(param);
0867: break;
0868: case 0x19:
0869: newPAP.setDyaAbs(param);
0870: break;
0871: case 0x1a:
0872: newPAP.setDxaWidth(param);
0873: break;
0874: case 0x1b:
0875: /** @todo handle paragraph postioning*/
0876: /*byte pcVert = (param & 0x0c) >> 2;
0877: byte pcHorz = param & 0x03;
0878: if(pcVert != 3)
0879: {
0880: newPAP._pcVert = pcVert;
0881: }
0882: if(pcHorz != 3)
0883: {
0884: newPAP._pcHorz = pcHorz;
0885: }*/
0886: break;
0887: case 0x1c:
0888: //newPAP.setBrcTop1((short)param);
0889: break;
0890: case 0x1d:
0891: //newPAP.setBrcLeft1((short)param);
0892: break;
0893: case 0x1e:
0894: //newPAP.setBrcBottom1((short)param);
0895: break;
0896: case 0x1f:
0897: //newPAP.setBrcRight1((short)param);
0898: break;
0899: case 0x20:
0900: //newPAP.setBrcBetween1((short)param);
0901: break;
0902: case 0x21:
0903: //newPAP.setBrcBar1((byte)param);
0904: break;
0905: case 0x22:
0906: newPAP.setDxaFromText(param);
0907: break;
0908: case 0x23:
0909: newPAP.setWr((byte) param);
0910: break;
0911: case 0x24:
0912: short[] brcTop = newPAP.getBrcTop();
0913: brcTop[0] = (short) LittleEndian.getShort(grpprl,
0914: offset - 4);
0915: brcTop[1] = (short) LittleEndian.getShort(grpprl,
0916: offset - 2);
0917: break;
0918: case 0x25:
0919: short[] brcLeft = newPAP.getBrcLeft();
0920: brcLeft[0] = (short) LittleEndian.getShort(grpprl,
0921: offset - 4);
0922: brcLeft[1] = (short) LittleEndian.getShort(grpprl,
0923: offset - 2);
0924: break;
0925: case 0x26:
0926: short[] brcBottom = newPAP.getBrcBottom();
0927: brcBottom[0] = (short) LittleEndian.getShort(grpprl,
0928: offset - 4);
0929: brcBottom[1] = (short) LittleEndian.getShort(grpprl,
0930: offset - 2);
0931: break;
0932: case 0x27:
0933: short[] brcRight = newPAP.getBrcRight();
0934: brcRight[0] = (short) LittleEndian.getShort(grpprl,
0935: offset - 4);
0936: brcRight[1] = (short) LittleEndian.getShort(grpprl,
0937: offset - 2);
0938: break;
0939: case 0x28:
0940: short[] brcBetween = newPAP.getBrcBetween();
0941: brcBetween[0] = (short) LittleEndian.getShort(grpprl,
0942: offset - 4);
0943: brcBetween[1] = (short) LittleEndian.getShort(grpprl,
0944: offset - 2);
0945: break;
0946: case 0x29:
0947: short[] brcBar = newPAP.getBrcBar();
0948: brcBar[0] = (short) LittleEndian.getShort(grpprl,
0949: offset - 4);
0950: brcBar[1] = (short) LittleEndian.getShort(grpprl,
0951: offset - 2);
0952: break;
0953: case 0x2a:
0954: newPAP.setFNoAutoHyph((byte) param);
0955: break;
0956: case 0x2b:
0957: newPAP.setDyaHeight(param);
0958: break;
0959: case 0x2c:
0960: newPAP.setDcs((short) param);
0961: break;
0962: case 0x2d:
0963: newPAP.setShd((short) param);
0964: break;
0965: case 0x2e:
0966: newPAP.setDyaFromText(param);
0967: break;
0968: case 0x2f:
0969: newPAP.setDxaFromText(param);
0970: break;
0971: case 0x30:
0972: newPAP.setFLocked((byte) param);
0973: break;
0974: case 0x31:
0975: newPAP.setFWidowControl((byte) param);
0976: break;
0977: case 0x32:
0978: //undocumented
0979: break;
0980: case 0x33:
0981: newPAP.setFKinsoku((byte) param);
0982: break;
0983: case 0x34:
0984: newPAP.setFWordWrap((byte) param);
0985: break;
0986: case 0x35:
0987: newPAP.setFOverflowPunct((byte) param);
0988: break;
0989: case 0x36:
0990: newPAP.setFTopLinePunct((byte) param);
0991: break;
0992: case 0x37:
0993: newPAP.setFAutoSpaceDE((byte) param);
0994: break;
0995: case 0x38:
0996: newPAP.setFAutoSpaceDN((byte) param);
0997: break;
0998: case 0x39:
0999: newPAP.setWAlignFont(param);
1000: break;
1001: case 0x3a:
1002: newPAP.setFontAlign((short) param);
1003: break;
1004: case 0x3b:
1005: //obsolete
1006: break;
1007: case 0x3e:
1008: newPAP.setAnld(varParam);
1009: break;
1010: case 0x3f:
1011: //don't really need this. spec is confusing regarding this
1012: //sprm
1013: break;
1014: case 0x40:
1015: //newPAP._lvl = param;
1016: break;
1017: case 0x41:
1018: //?
1019: break;
1020: case 0x43:
1021: //?
1022: break;
1023: case 0x44:
1024: //?
1025: break;
1026: case 0x45:
1027: if (spra == 6) {
1028: newPAP.setNumrm(varParam);
1029: } else {
1030: /**@todo handle large PAPX from data stream*/
1031: }
1032: break;
1033:
1034: case 0x47:
1035: newPAP.setFUsePgsuSettings((byte) param);
1036: break;
1037: case 0x48:
1038: newPAP.setFAdjustRight((byte) param);
1039: break;
1040: default:
1041: break;
1042: }
1043: }
1044:
1045: /**
1046: * Used to uncompress a table property. Performs an operation defined
1047: * by a sprm stored in a tapx.
1048: *
1049: * @param newTAP The TableProperties object to perform the operation on.
1050: * @param operand The operand that defines this operation.
1051: * @param param The parameter for this operation.
1052: * @param varParam Variable length parameter for this operation.
1053: */
1054: static void doTAPOperation(TableProperties newTAP, int operand,
1055: int param, byte[] varParam) {
1056: switch (operand) {
1057: case 0:
1058: newTAP.setJc((short) param);
1059: break;
1060: case 0x01: {
1061: short[] rgdxaCenter = newTAP.getRgdxaCenter();
1062: short itcMac = newTAP.getItcMac();
1063: int adjust = param
1064: - (rgdxaCenter[0] + newTAP.getDxaGapHalf());
1065: for (int x = 0; x < itcMac; x++) {
1066: rgdxaCenter[x] += adjust;
1067: }
1068: break;
1069: }
1070: case 0x02: {
1071: short[] rgdxaCenter = newTAP.getRgdxaCenter();
1072: if (rgdxaCenter != null) {
1073: int adjust = newTAP.getDxaGapHalf() - param;
1074: rgdxaCenter[0] += adjust;
1075: }
1076: newTAP.setDxaGapHalf(param);
1077: break;
1078: }
1079: case 0x03:
1080: newTAP.setFCantSplit(getFlag(param));
1081: break;
1082: case 0x04:
1083: newTAP.setFTableHeader(getFlag(param));
1084: break;
1085: case 0x05: {
1086: short[] brcTop = newTAP.getBrcTop();
1087: short[] brcLeft = newTAP.getBrcLeft();
1088: short[] brcBottom = newTAP.getBrcBottom();
1089: short[] brcRight = newTAP.getBrcRight();
1090: short[] brcVertical = newTAP.getBrcVertical();
1091: short[] brcHorizontal = newTAP.getBrcHorizontal();
1092:
1093: brcTop[0] = LittleEndian.getShort(varParam, 0);
1094: brcTop[1] = LittleEndian.getShort(varParam, 2);
1095:
1096: brcLeft[0] = LittleEndian.getShort(varParam, 4);
1097: brcLeft[1] = LittleEndian.getShort(varParam, 6);
1098:
1099: brcBottom[0] = LittleEndian.getShort(varParam, 8);
1100: brcBottom[1] = LittleEndian.getShort(varParam, 10);
1101:
1102: brcRight[0] = LittleEndian.getShort(varParam, 12);
1103: brcRight[1] = LittleEndian.getShort(varParam, 14);
1104:
1105: brcHorizontal[0] = LittleEndian.getShort(varParam, 16);
1106: brcHorizontal[1] = LittleEndian.getShort(varParam, 18);
1107:
1108: brcVertical[0] = LittleEndian.getShort(varParam, 20);
1109: brcVertical[1] = LittleEndian.getShort(varParam, 22);
1110: break;
1111: }
1112: case 0x06:
1113: //obsolete, used in word 1.x
1114: break;
1115: case 0x07:
1116: newTAP.setDyaRowHeight(param);
1117: break;
1118: case 0x08: {
1119: short[] rgdxaCenter = new short[varParam[0] + 1];
1120: TableCellDescriptor[] rgtc = new TableCellDescriptor[varParam[0]];
1121: short itcMac = varParam[0];
1122: //I use varParam[0] and newTAP._itcMac interchangably
1123: newTAP.setItcMac(itcMac);
1124: newTAP.setRgdxaCenter(rgdxaCenter);
1125: newTAP.setRgtc(rgtc);
1126:
1127: for (int x = 0; x < itcMac; x++) {
1128: rgdxaCenter[x] = LittleEndian.getShort(varParam,
1129: 1 + (x * 2));
1130: rgtc[x] = TableCellDescriptor.convertBytesToTC(
1131: varParam, 1 + ((itcMac + 1) * 2) + (x * 20));
1132: }
1133: rgdxaCenter[itcMac] = LittleEndian.getShort(varParam,
1134: 1 + (itcMac * 2));
1135: break;
1136: }
1137: case 0x09:
1138: /** @todo handle cell shading*/
1139: break;
1140: case 0x0a:
1141: /** @todo handle word defined table styles*/
1142: break;
1143: case 0x20: {
1144: TCAbstractType[] rgtc = newTAP.getRgtc();
1145:
1146: for (int x = varParam[0]; x < varParam[1]; x++) {
1147:
1148: if ((varParam[2] & 0x08) > 0) {
1149: short[] brcRight = rgtc[x].getBrcRight();
1150: brcRight[0] = LittleEndian.getShort(varParam, 6);
1151: brcRight[1] = LittleEndian.getShort(varParam, 8);
1152: } else if ((varParam[2] & 0x04) > 0) {
1153: short[] brcBottom = rgtc[x].getBrcBottom();
1154: brcBottom[0] = LittleEndian.getShort(varParam, 6);
1155: brcBottom[1] = LittleEndian.getShort(varParam, 8);
1156: } else if ((varParam[2] & 0x02) > 0) {
1157: short[] brcLeft = rgtc[x].getBrcLeft();
1158: brcLeft[0] = LittleEndian.getShort(varParam, 6);
1159: brcLeft[1] = LittleEndian.getShort(varParam, 8);
1160: } else if ((varParam[2] & 0x01) > 0) {
1161: short[] brcTop = rgtc[x].getBrcTop();
1162: brcTop[0] = LittleEndian.getShort(varParam, 6);
1163: brcTop[1] = LittleEndian.getShort(varParam, 8);
1164: }
1165: }
1166: break;
1167: }
1168: case 0x21:
1169: int index = (param & 0xff000000) >> 24;
1170: int count = (param & 0x00ff0000) >> 16;
1171: int width = (param & 0x0000ffff);
1172: int itcMac = newTAP.getItcMac();
1173:
1174: short[] rgdxaCenter = new short[itcMac + count + 1];
1175: TableCellDescriptor[] rgtc = new TableCellDescriptor[itcMac
1176: + count];
1177: if (index >= itcMac) {
1178: index = itcMac;
1179: System.arraycopy(newTAP.getRgdxaCenter(), 0,
1180: rgdxaCenter, 0, itcMac + 1);
1181: System.arraycopy(newTAP.getRgtc(), 0, rgtc, 0, itcMac);
1182: } else {
1183: //copy rgdxaCenter
1184: System.arraycopy(newTAP.getRgdxaCenter(), 0,
1185: rgdxaCenter, 0, index + 1);
1186: System.arraycopy(newTAP.getRgdxaCenter(), index + 1,
1187: rgdxaCenter, index + count, itcMac - (index));
1188: //copy rgtc
1189: System.arraycopy(newTAP.getRgtc(), 0, rgtc, 0, index);
1190: System.arraycopy(newTAP.getRgtc(), index, rgtc, index
1191: + count, itcMac - index);
1192: }
1193:
1194: for (int x = index; x < index + count; x++) {
1195: rgtc[x] = new TableCellDescriptor();
1196: rgdxaCenter[x] = (short) (rgdxaCenter[x - 1] + width);
1197: }
1198: rgdxaCenter[index + count] = (short) (rgdxaCenter[(index + count) - 1] + width);
1199: break;
1200: /**@todo handle table sprms from complex files*/
1201: case 0x22:
1202: case 0x23:
1203: case 0x24:
1204: case 0x25:
1205: case 0x26:
1206: case 0x27:
1207: case 0x28:
1208: case 0x29:
1209: case 0x2a:
1210: case 0x2b:
1211: case 0x2c:
1212: break;
1213: default:
1214: break;
1215: }
1216: }
1217:
1218: /**
1219: * Used in decompression of a sepx. This performs an operation defined by
1220: * a single sprm.
1221: *
1222: * @param newSEP The SectionProperty to perfrom the operation on.
1223: * @param operand The operation to perform.
1224: * @param param The operation's parameter.
1225: * @param varParam The operation variable length parameter.
1226: */
1227: static void doSEPOperation(SectionProperties newSEP, int operand,
1228: int param, byte[] varParam) {
1229: switch (operand) {
1230: case 0:
1231: newSEP.setCnsPgn((byte) param);
1232: break;
1233: case 0x1:
1234: newSEP.setIHeadingPgn((byte) param);
1235: break;
1236: case 0x2:
1237: newSEP.setOlstAnm(varParam);
1238: break;
1239: case 0x3:
1240: //not quite sure
1241: break;
1242: case 0x4:
1243: //not quite sure
1244: break;
1245: case 0x5:
1246: newSEP.setFEvenlySpaced(getFlag(param));
1247: break;
1248: case 0x6:
1249: newSEP.setFUnlocked(getFlag(param));
1250: break;
1251: case 0x7:
1252: newSEP.setDmBinFirst((short) param);
1253: break;
1254: case 0x8:
1255: newSEP.setDmBinOther((short) param);
1256: break;
1257: case 0x9:
1258: newSEP.setBkc((byte) param);
1259: break;
1260: case 0xa:
1261: newSEP.setFTitlePage(getFlag(param));
1262: break;
1263: case 0xb:
1264: newSEP.setCcolM1((short) param);
1265: break;
1266: case 0xc:
1267: newSEP.setDxaColumns(param);
1268: break;
1269: case 0xd:
1270: newSEP.setFAutoPgn(getFlag(param));
1271: break;
1272: case 0xe:
1273: newSEP.setNfcPgn((byte) param);
1274: break;
1275: case 0xf:
1276: newSEP.setDyaPgn((short) param);
1277: break;
1278: case 0x10:
1279: newSEP.setDxaPgn((short) param);
1280: break;
1281: case 0x11:
1282: newSEP.setFPgnRestart(getFlag(param));
1283: break;
1284: case 0x12:
1285: newSEP.setFEndNote(getFlag(param));
1286: break;
1287: case 0x13:
1288: newSEP.setLnc((byte) param);
1289: break;
1290: case 0x14:
1291: newSEP.setGrpfIhdt((byte) param);
1292: break;
1293: case 0x15:
1294: newSEP.setNLnnMod((short) param);
1295: break;
1296: case 0x16:
1297: newSEP.setDxaLnn(param);
1298: break;
1299: case 0x17:
1300: newSEP.setDyaHdrTop(param);
1301: break;
1302: case 0x18:
1303: newSEP.setDyaHdrBottom(param);
1304: break;
1305: case 0x19:
1306: newSEP.setFLBetween(getFlag(param));
1307: break;
1308: case 0x1a:
1309: newSEP.setVjc((byte) param);
1310: break;
1311: case 0x1b:
1312: newSEP.setLnnMin((short) param);
1313: break;
1314: case 0x1c:
1315: newSEP.setPgnStart((short) param);
1316: break;
1317: case 0x1d:
1318: newSEP.setDmOrientPage((byte) param);
1319: break;
1320: case 0x1e:
1321: //nothing
1322: break;
1323: case 0x1f:
1324: newSEP.setXaPage(param);
1325: break;
1326: case 0x20:
1327: newSEP.setYaPage(param);
1328: break;
1329: case 0x21:
1330: newSEP.setDxaLeft(param);
1331: break;
1332: case 0x22:
1333: newSEP.setDxaRight(param);
1334: break;
1335: case 0x23:
1336: newSEP.setDyaTop(param);
1337: break;
1338: case 0x24:
1339: newSEP.setDyaBottom(param);
1340: break;
1341: case 0x25:
1342: newSEP.setDzaGutter(param);
1343: break;
1344: case 0x26:
1345: newSEP.setDmPaperReq((short) param);
1346: break;
1347: case 0x27:
1348: newSEP.setFPropMark(getFlag(varParam[0]));
1349: break;
1350: case 0x28:
1351: break;
1352: case 0x29:
1353: break;
1354: case 0x2a:
1355: break;
1356: case 0x2b:
1357: short[] brcTop = newSEP.getBrcTop();
1358: brcTop[0] = (short) (param & 0xffff);
1359: brcTop[1] = (short) ((param & 0xffff0000) >> 16);
1360: break;
1361: case 0x2c:
1362: short[] brcLeft = newSEP.getBrcLeft();
1363: brcLeft[0] = (short) (param & 0xffff);
1364: brcLeft[1] = (short) ((param & 0xffff0000) >> 16);
1365: break;
1366: case 0x2d:
1367: short[] brcBottom = newSEP.getBrcBottom();
1368: brcBottom[0] = (short) (param & 0xffff);
1369: brcBottom[1] = (short) ((param & 0xffff0000) >> 16);
1370: break;
1371: case 0x2e:
1372: short[] brcRight = newSEP.getBrcRight();
1373: brcRight[0] = (short) (param & 0xffff);
1374: brcRight[1] = (short) ((param & 0xffff0000) >> 16);
1375: break;
1376: case 0x2f:
1377: newSEP.setPgbProp(param);
1378: break;
1379: case 0x30:
1380: newSEP.setDxtCharSpace(param);
1381: break;
1382: case 0x31:
1383: newSEP.setDyaLinePitch(param);
1384: break;
1385: case 0x33:
1386: newSEP.setWTextFlow((short) param);
1387: break;
1388: default:
1389: break;
1390: }
1391:
1392: }
1393:
1394: /**
1395: * Converts an byte value into a boolean. The byte parameter can be 1,0, 128,
1396: * or 129. if it is 128, this function returns the same value as oldVal. If
1397: * it is 129, this function returns !oldVal. This is used for certain sprms
1398: *
1399: * @param x The byte value to convert.
1400: * @param oldVal The old boolean value.
1401: *
1402: * @return A boolean whose value depends on x and oldVal.
1403: */
1404: private static boolean getCHPFlag(byte x, boolean oldVal) {
1405: switch (x) {
1406: case 0:
1407: return false;
1408: case 1:
1409: return true;
1410: case (byte) 0x80:
1411: return oldVal;
1412: case (byte) 0x81:
1413: return !oldVal;
1414: default:
1415: return false;
1416: }
1417: }
1418:
1419: /**
1420: * Converts an int into a boolean. If the int is non-zero, it returns true.
1421: * Otherwise it returns false.
1422: *
1423: * @param x The int to convert.
1424: *
1425: * @return A boolean whose value depends on x.
1426: */
1427: public static boolean getFlag(int x) {
1428: if (x != 0) {
1429: return true;
1430: } else {
1431: return false;
1432: }
1433: }
1434: }
|