/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: WseTextRun.java,v $
* $Revision: 1.4 $
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
package org.openoffice.xmerge.converter.xml.sxw.wordsmith;
import org.openoffice.xmerge.converter.xml.TextStyle;
import org.openoffice.xmerge.converter.xml.StyleCatalog;
import java.awt.Color;
/**
* <p>This class represents a text run (aka text atom) in a WordSmith
* document.</p>
*
* <p>WordSmith represents a text run as follows:</p>
*
* <p><ul><li>
* 1 byte Value of "1", indicating beginning of a text atom
* </li><li>
* 2 bytes Length of text (does not include attributes, this length field,
* etc)
* </li><li>
* 1 byte Font index - Index in the font table of font to be used
* </li><li>
* 1 byte Font size (DJP: get details of representation)
* </li><li>
* 1 byte Color index - Index in the color table of font color to be used
* </li><li>
* 1 byte Modifiers - bit flags for bold, italic, etc
* </li><li>
* n bytes Text - the actual text
* </li></ul></p>
*
* @author David Proulx
*/
class WseTextRun extends Wse {
/** Font specifier. This is an index into the font table. */
private byte fontIndex = 0;
private String fontName = null;
/** Size of the font. */
private byte fontSize = 0;
/**
* Color of the font. This is an index into the color table.
* High nibble is background color index, low nibble is font color
* index.
*/
private byte colorIndex = 0;
/**
* Reference to color table for color lookups.
*/
private WseColorTable ct;
/**
* The modifiers for the text run. (Mostly) Bitwise flags. The "_TOKEN"
* values are not yet implemented in this converter. They may not even
* be implemented in WordSmith yet.
*/
private byte modifiers = 0;
final public static int BOLD = 0x01;
final public static int ITALIC = 0x02;
final public static int UNDERLINE = 0x04;
final public static int STRIKETHRU = 0x08;
final public static int SUPERSCRIPT = 0x10;
final public static int SUBSCRIPT = 0x20;
final public static int LINK = 0x40;
final public static int CUSTOM_TOKEN = 0x80;
final public static int IMAGE_TOKEN = 0x80;
final public static int BOOKMARK_TOKEN = 0x81;
final public static int ANNOTATION_TOKEN = 0x82;
final public static int LINK_TOKEN = 0x83;
/** The actual text. */
private String text;
StyleCatalog sc;
/**
* Constructor for use when going from DOM to WordSmith.
*
* @param txt The text.
* @param t The text style.
* @param sc The <code>StyleCatalog</code>.
* @param ft The font table.
* @param ct The color Table.
*/
public WseTextRun(String txt, TextStyle t, StyleCatalog sc,
WseFontTable ft, WseColorTable ct) {
this.sc = sc;
this.ct = ct;
TextStyle ts = (TextStyle)t.getResolved();
if (ts.isSet(TextStyle.BOLD) && ts.getAttribute(TextStyle.BOLD))
modifiers |= BOLD;
if (ts.isSet(TextStyle.ITALIC) && ts.getAttribute(TextStyle.ITALIC))
modifiers |= ITALIC;
if (ts.isSet(TextStyle.UNDERLINE) && ts.getAttribute(TextStyle.UNDERLINE))
modifiers |= UNDERLINE;
if (ts.isSet(TextStyle.STRIKETHRU) && ts.getAttribute(TextStyle.STRIKETHRU))
modifiers |= STRIKETHRU;
if (ts.isSet(TextStyle.SUPERSCRIPT) && ts.getAttribute(TextStyle.SUPERSCRIPT))
modifiers |= SUPERSCRIPT;
if (ts.isSet(TextStyle.SUBSCRIPT) && ts.getAttribute(TextStyle.SUBSCRIPT))
modifiers |= SUBSCRIPT;
fontSize = (byte)(ts.getFontSize() * 2);
fontName = ts.getFontName();
fontIndex = (byte)ft.getFontIndex(fontName);
if (fontIndex == -1) {
ft.add(fontName);
fontIndex = (byte)ft.getFontIndex(fontName);
}
// Figure out the color index.
Color c = t.getFontColor();
if (c == null)
c = Color.black;
colorIndex = (byte)ct.findColor(c, true);
c = t.getBackgroundColor();
if (c == null)
c = Color.white;
colorIndex |= (byte)(ct.findColor(c, false) << 4);
text = txt;
}
/**
* Standard constructor for use when going from WordSmith to DOM.
*
* @param dataArray <code>byte</code> array.
* @param startIndex The start index.
* @param ft The font table.
* @param ct The color table.
*/
public WseTextRun(byte dataArray[], int startIndex, WseFontTable ft,
WseColorTable ct) {
this.ct = ct;
startIndex++; // Skip the leading "1"
int textLen = ((dataArray[startIndex] << 8)
| (dataArray[startIndex+1] & 0xFF));
startIndex += 2;
fontIndex = dataArray[startIndex++];
if (ft != null)
fontName = ft.getFontName(fontIndex);
fontSize = dataArray[startIndex++];
colorIndex = dataArray[startIndex++];
modifiers = dataArray[startIndex++];
text = new String(dataArray, startIndex, textLen);
startIndex += textLen; // skip the text
}
/**
* Given a <code>byte</code> sequence, assumed to be a text run,
* compute the index of the first byte past the text run.
*
* @param dataArray <code>byte</code> array.
* @param startIndex The start index
*
* @return The index of the first <code>byte</code> past the
* text run.
*/
public static int computeNewIndex(byte dataArray[], int startIndex) {
startIndex++; // Skip the leading "1"
int textLen = ((dataArray[startIndex] << 8)
| (dataArray[startIndex+1] & 0xFF));
startIndex += 2;
startIndex += 4; // skip attributes
// text = new String(dataArray, startIndex, textLen);
startIndex += textLen; // skip the text
return startIndex;
}
/**
* Return true if the sequence starting at
* <code>dataArray[startIndex]</code> is a valid text run.
*
* @param dataArray <code>byte</code> array.
* @param startIndex The start index.
*
* @return true if the sequence starting at
* <code>dataArray[startIndex]</code> is a valid
* text run, false otherwise.
*/
public static boolean isValid(byte dataArray[], int startIndex) {
return (dataArray[startIndex] == 1);
}
/**
* Return the number of bytes needed to represent this text run.
*
* @return The number of bytes needed to represent this text run.
*/
int getByteCount() {
return text.length() + 7;
}
/**
* Return an <code>byte</code> array representing this text run.
*
* @return An <code>byte</code> array representing this text run.
*/
byte[] getBytes() {
short textLen = (short)text.length();
byte b[] = new byte[textLen + 7];
b[0] = 1;
b[1] = (byte)(textLen >> 8);
b[2] = (byte)(textLen & 0xFF);
b[3] = fontIndex;
b[4] = fontSize;
b[5] = colorIndex;
b[6] = modifiers;
byte[] txtBytes = text.getBytes();
System.arraycopy(txtBytes, 0, b, 7, textLen);
return b;
}
/**
* Return the text of this run.
*
* @return The text of this run.
*/
public String getText() {
return text;
}
/**
* Return a <code>TextStyle</code> that reflects the formatting
* of this run.
*
* @return A <code>TextStyle</code> that reflects the formatting
* of this run.
*/
public TextStyle makeStyle() {
int mod = 0;
if ((modifiers & BOLD) != 0) mod |= TextStyle.BOLD;
if ((modifiers & ITALIC) != 0) mod |= TextStyle.ITALIC;
if ((modifiers & UNDERLINE) != 0) mod |= TextStyle.UNDERLINE;
if ((modifiers & STRIKETHRU) != 0)
mod |= TextStyle.STRIKETHRU;
if ((modifiers & SUPERSCRIPT) != 0) mod |= TextStyle.SUPERSCRIPT;
if ((modifiers & SUBSCRIPT) != 0) mod |= TextStyle.SUBSCRIPT;
int mask = TextStyle.BOLD | TextStyle.ITALIC
| TextStyle.UNDERLINE
| TextStyle.STRIKETHRU | TextStyle.SUPERSCRIPT
| TextStyle.SUBSCRIPT;
TextStyle x = new TextStyle(null, "text", null, mask,
mod, (int)(fontSize/2), fontName, sc);
// If color table is available, set the colors.
if (ct != null) {
Color fc = ct.getColor(colorIndex & 0xF, true);
Color bc = ct.getColor(colorIndex >> 4, false);
x.setColors(fc, bc);
}
return x;
}
/**
* Display debug information.
*/
public void dump() {
System.out.print("TEXT RUN: fontIndex = " + fontIndex
+ " fontsize = " + fontSize
+ " colorIndex = " + colorIndex
+ " ");
if ((modifiers & BOLD) != 0) System.out.print("BOLD,");
if ((modifiers & ITALIC) != 0) System.out.print("ITALIC,");
if ((modifiers & UNDERLINE) != 0) System.out.print("UNDERLINE,");
if ((modifiers & STRIKETHRU) != 0) System.out.print("STRIKETHRU,");
if ((modifiers & SUPERSCRIPT) != 0) System.out.print("SUPERSCRIPT,");
if ((modifiers & SUBSCRIPT) != 0) System.out.print("SUBSCRIPT,");
System.out.println("\n" + text);
}
}