feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
229
jdkSrc/jdk8/javax/swing/text/rtf/AbstractFilter.java
Normal file
229
jdkSrc/jdk8/javax/swing/text/rtf/AbstractFilter.java
Normal file
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.text.rtf;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.*;
|
||||
|
||||
/**
|
||||
* A generic superclass for streams which read and parse text
|
||||
* consisting of runs of characters interspersed with occasional
|
||||
* ``specials'' (formatting characters).
|
||||
*
|
||||
* <p> Most of the functionality
|
||||
* of this class would be redundant except that the
|
||||
* <code>ByteToChar</code> converters
|
||||
* are suddenly private API. Presumably this class will disappear
|
||||
* when the API is made public again. (sigh) That will also let us handle
|
||||
* multibyte character sets...
|
||||
*
|
||||
* <P> A subclass should override at least <code>write(char)</code>
|
||||
* and <code>writeSpecial(int)</code>. For efficiency's sake it's a
|
||||
* good idea to override <code>write(String)</code> as well. The subclass'
|
||||
* initializer may also install appropriate translation and specials tables.
|
||||
*
|
||||
* @see OutputStream
|
||||
*/
|
||||
abstract class AbstractFilter extends OutputStream
|
||||
{
|
||||
/** A table mapping bytes to characters */
|
||||
protected char translationTable[];
|
||||
/** A table indicating which byte values should be interpreted as
|
||||
* characters and which should be treated as formatting codes */
|
||||
protected boolean specialsTable[];
|
||||
|
||||
/** A translation table which does ISO Latin-1 (trivial) */
|
||||
static final char latin1TranslationTable[];
|
||||
/** A specials table which indicates that no characters are special */
|
||||
static final boolean noSpecialsTable[];
|
||||
/** A specials table which indicates that all characters are special */
|
||||
static final boolean allSpecialsTable[];
|
||||
|
||||
static {
|
||||
int i;
|
||||
|
||||
noSpecialsTable = new boolean[256];
|
||||
for (i = 0; i < 256; i++)
|
||||
noSpecialsTable[i] = false;
|
||||
|
||||
allSpecialsTable = new boolean[256];
|
||||
for (i = 0; i < 256; i++)
|
||||
allSpecialsTable[i] = true;
|
||||
|
||||
latin1TranslationTable = new char[256];
|
||||
for (i = 0; i < 256; i++)
|
||||
latin1TranslationTable[i] = (char)i;
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method that reads text from a FileInputStream
|
||||
* and writes it to the receiver.
|
||||
* The format in which the file
|
||||
* is read is determined by the concrete subclass of
|
||||
* AbstractFilter to which this method is sent.
|
||||
* <p>This method does not close the receiver after reaching EOF on
|
||||
* the input stream.
|
||||
* The user must call <code>close()</code> to ensure that all
|
||||
* data are processed.
|
||||
*
|
||||
* @param in An InputStream providing text.
|
||||
*/
|
||||
public void readFromStream(InputStream in)
|
||||
throws IOException
|
||||
{
|
||||
byte buf[];
|
||||
int count;
|
||||
|
||||
buf = new byte[16384];
|
||||
|
||||
while(true) {
|
||||
count = in.read(buf);
|
||||
if (count < 0)
|
||||
break;
|
||||
|
||||
this.write(buf, 0, count);
|
||||
}
|
||||
}
|
||||
|
||||
public void readFromReader(Reader in)
|
||||
throws IOException
|
||||
{
|
||||
char buf[];
|
||||
int count;
|
||||
|
||||
buf = new char[2048];
|
||||
|
||||
while(true) {
|
||||
count = in.read(buf);
|
||||
if (count < 0)
|
||||
break;
|
||||
for (int i = 0; i < count; i++) {
|
||||
this.write(buf[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AbstractFilter()
|
||||
{
|
||||
translationTable = latin1TranslationTable;
|
||||
specialsTable = noSpecialsTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the abstract method of OutputStream, of which this class
|
||||
* is a subclass.
|
||||
*/
|
||||
public void write(int b)
|
||||
throws IOException
|
||||
{
|
||||
if (b < 0)
|
||||
b += 256;
|
||||
if (specialsTable[b])
|
||||
writeSpecial(b);
|
||||
else {
|
||||
char ch = translationTable[b];
|
||||
if (ch != (char)0)
|
||||
write(ch);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the buffer-at-a-time write method for greater
|
||||
* efficiency.
|
||||
*
|
||||
* <p> <strong>PENDING:</strong> Does <code>write(byte[])</code>
|
||||
* call <code>write(byte[], int, int)</code> or is it the other way
|
||||
* around?
|
||||
*/
|
||||
public void write(byte[] buf, int off, int len)
|
||||
throws IOException
|
||||
{
|
||||
StringBuilder accumulator = null;
|
||||
while (len > 0) {
|
||||
short b = (short)buf[off];
|
||||
|
||||
// stupid signed bytes
|
||||
if (b < 0)
|
||||
b += 256;
|
||||
|
||||
if (specialsTable[b]) {
|
||||
if (accumulator != null) {
|
||||
write(accumulator.toString());
|
||||
accumulator = null;
|
||||
}
|
||||
writeSpecial(b);
|
||||
} else {
|
||||
char ch = translationTable[b];
|
||||
if (ch != (char)0) {
|
||||
if (accumulator == null)
|
||||
accumulator = new StringBuilder();
|
||||
accumulator.append(ch);
|
||||
}
|
||||
}
|
||||
|
||||
len --;
|
||||
off ++;
|
||||
}
|
||||
|
||||
if (accumulator != null)
|
||||
write(accumulator.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Hopefully, all subclasses will override this method to accept strings
|
||||
* of text, but if they don't, AbstractFilter's implementation
|
||||
* will spoon-feed them via <code>write(char)</code>.
|
||||
*
|
||||
* @param s The string of non-special characters written to the
|
||||
* OutputStream.
|
||||
*/
|
||||
public void write(String s)
|
||||
throws IOException
|
||||
{
|
||||
int index, length;
|
||||
|
||||
length = s.length();
|
||||
for(index = 0; index < length; index ++) {
|
||||
write(s.charAt(index));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must provide an implementation of this method which
|
||||
* accepts a single (non-special) character.
|
||||
*
|
||||
* @param ch The character written to the OutputStream.
|
||||
*/
|
||||
protected abstract void write(char ch) throws IOException;
|
||||
|
||||
/**
|
||||
* Subclasses must provide an implementation of this method which
|
||||
* accepts a single special byte. No translation is performed
|
||||
* on specials.
|
||||
*
|
||||
* @param b The byte written to the OutputStream.
|
||||
*/
|
||||
protected abstract void writeSpecial(int b) throws IOException;
|
||||
}
|
||||
78
jdkSrc/jdk8/javax/swing/text/rtf/Constants.java
Normal file
78
jdkSrc/jdk8/javax/swing/text/rtf/Constants.java
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.text.rtf;
|
||||
|
||||
/**
|
||||
Class to hold dictionary keys used by the RTF reader/writer.
|
||||
These should be moved into StyleConstants.
|
||||
*/
|
||||
class Constants
|
||||
{
|
||||
/** An array of TabStops */
|
||||
static final String Tabs = "tabs";
|
||||
|
||||
/** The name of the character set the original RTF file was in */
|
||||
static final String RTFCharacterSet = "rtfCharacterSet";
|
||||
|
||||
/** Indicates the domain of a Style */
|
||||
static final String StyleType = "style:type";
|
||||
|
||||
/** Value for StyleType indicating a section style */
|
||||
static final String STSection = "section";
|
||||
/** Value for StyleType indicating a paragraph style */
|
||||
static final String STParagraph = "paragraph";
|
||||
/** Value for StyleType indicating a character style */
|
||||
static final String STCharacter = "character";
|
||||
|
||||
/** The style of the text following this style */
|
||||
static final String StyleNext = "style:nextStyle";
|
||||
|
||||
/** Whether the style is additive */
|
||||
static final String StyleAdditive = "style:additive";
|
||||
|
||||
/** Whether the style is hidden from the user */
|
||||
static final String StyleHidden = "style:hidden";
|
||||
|
||||
/* Miscellaneous character attributes */
|
||||
static final String Caps = "caps";
|
||||
static final String Deleted = "deleted";
|
||||
static final String Outline = "outl";
|
||||
static final String SmallCaps = "scaps";
|
||||
static final String Shadow = "shad";
|
||||
static final String Strikethrough = "strike";
|
||||
static final String Hidden = "v";
|
||||
|
||||
/* Miscellaneous document attributes */
|
||||
static final String PaperWidth = "paperw";
|
||||
static final String PaperHeight = "paperh";
|
||||
static final String MarginLeft = "margl";
|
||||
static final String MarginRight = "margr";
|
||||
static final String MarginTop = "margt";
|
||||
static final String MarginBottom = "margb";
|
||||
static final String GutterWidth = "gutter";
|
||||
|
||||
/* This is both a document and a paragraph attribute */
|
||||
static final String WidowControl = "widowctrl";
|
||||
}
|
||||
124
jdkSrc/jdk8/javax/swing/text/rtf/MockAttributeSet.java
Normal file
124
jdkSrc/jdk8/javax/swing/text/rtf/MockAttributeSet.java
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.text.rtf;
|
||||
|
||||
import java.util.Dictionary;
|
||||
import java.util.Enumeration;
|
||||
import javax.swing.text.AttributeSet;
|
||||
import javax.swing.text.MutableAttributeSet;
|
||||
|
||||
|
||||
/* This AttributeSet is made entirely out of tofu and Ritz Crackers
|
||||
and yet has a remarkably attribute-set-like interface! */
|
||||
class MockAttributeSet
|
||||
implements AttributeSet, MutableAttributeSet
|
||||
{
|
||||
public Dictionary<Object, Object> backing;
|
||||
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return backing.isEmpty();
|
||||
}
|
||||
|
||||
public int getAttributeCount()
|
||||
{
|
||||
return backing.size();
|
||||
}
|
||||
|
||||
public boolean isDefined(Object name)
|
||||
{
|
||||
return ( backing.get(name) ) != null;
|
||||
}
|
||||
|
||||
public boolean isEqual(AttributeSet attr)
|
||||
{
|
||||
throw new InternalError("MockAttributeSet: charade revealed!");
|
||||
}
|
||||
|
||||
public AttributeSet copyAttributes()
|
||||
{
|
||||
throw new InternalError("MockAttributeSet: charade revealed!");
|
||||
}
|
||||
|
||||
public Object getAttribute(Object name)
|
||||
{
|
||||
return backing.get(name);
|
||||
}
|
||||
|
||||
public void addAttribute(Object name, Object value)
|
||||
{
|
||||
backing.put(name, value);
|
||||
}
|
||||
|
||||
public void addAttributes(AttributeSet attr)
|
||||
{
|
||||
Enumeration as = attr.getAttributeNames();
|
||||
while(as.hasMoreElements()) {
|
||||
Object el = as.nextElement();
|
||||
backing.put(el, attr.getAttribute(el));
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAttribute(Object name)
|
||||
{
|
||||
backing.remove(name);
|
||||
}
|
||||
|
||||
public void removeAttributes(AttributeSet attr)
|
||||
{
|
||||
throw new InternalError("MockAttributeSet: charade revealed!");
|
||||
}
|
||||
|
||||
public void removeAttributes(Enumeration<?> en)
|
||||
{
|
||||
throw new InternalError("MockAttributeSet: charade revealed!");
|
||||
}
|
||||
|
||||
public void setResolveParent(AttributeSet pp)
|
||||
{
|
||||
throw new InternalError("MockAttributeSet: charade revealed!");
|
||||
}
|
||||
|
||||
|
||||
public Enumeration getAttributeNames()
|
||||
{
|
||||
return backing.keys();
|
||||
}
|
||||
|
||||
public boolean containsAttribute(Object name, Object value)
|
||||
{
|
||||
throw new InternalError("MockAttributeSet: charade revealed!");
|
||||
}
|
||||
|
||||
public boolean containsAttributes(AttributeSet attr)
|
||||
{
|
||||
throw new InternalError("MockAttributeSet: charade revealed!");
|
||||
}
|
||||
|
||||
public AttributeSet getResolveParent()
|
||||
{
|
||||
throw new InternalError("MockAttributeSet: charade revealed!");
|
||||
}
|
||||
}
|
||||
67
jdkSrc/jdk8/javax/swing/text/rtf/RTFAttribute.java
Normal file
67
jdkSrc/jdk8/javax/swing/text/rtf/RTFAttribute.java
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.text.rtf;
|
||||
|
||||
import javax.swing.text.AttributeSet;
|
||||
import javax.swing.text.MutableAttributeSet;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This interface describes a class which defines a 1-1 mapping between
|
||||
* an RTF keyword and a SwingText attribute.
|
||||
*/
|
||||
interface RTFAttribute
|
||||
{
|
||||
static final int D_CHARACTER = 0;
|
||||
static final int D_PARAGRAPH = 1;
|
||||
static final int D_SECTION = 2;
|
||||
static final int D_DOCUMENT = 3;
|
||||
static final int D_META = 4;
|
||||
|
||||
/* These next three should really be public variables,
|
||||
but you can't declare public variables in an interface... */
|
||||
/* int domain; */
|
||||
public int domain();
|
||||
/* String swingName; */
|
||||
public Object swingName();
|
||||
/* String rtfName; */
|
||||
public String rtfName();
|
||||
|
||||
public boolean set(MutableAttributeSet target);
|
||||
public boolean set(MutableAttributeSet target, int parameter);
|
||||
|
||||
public boolean setDefault(MutableAttributeSet target);
|
||||
|
||||
/* TODO: This method is poorly thought out */
|
||||
public boolean write(AttributeSet source,
|
||||
RTFGenerator target,
|
||||
boolean force)
|
||||
throws IOException;
|
||||
|
||||
public boolean writeValue(Object value,
|
||||
RTFGenerator target,
|
||||
boolean force)
|
||||
throws IOException;
|
||||
}
|
||||
421
jdkSrc/jdk8/javax/swing/text/rtf/RTFAttributes.java
Normal file
421
jdkSrc/jdk8/javax/swing/text/rtf/RTFAttributes.java
Normal file
@@ -0,0 +1,421 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.text.rtf;
|
||||
|
||||
import javax.swing.text.StyleConstants;
|
||||
import javax.swing.text.AttributeSet;
|
||||
import javax.swing.text.MutableAttributeSet;
|
||||
import javax.swing.text.TabStop;
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
class RTFAttributes
|
||||
{
|
||||
static RTFAttribute attributes[];
|
||||
|
||||
static {
|
||||
Vector<RTFAttribute> a = new Vector<RTFAttribute>();
|
||||
int CHR = RTFAttribute.D_CHARACTER;
|
||||
int PGF = RTFAttribute.D_PARAGRAPH;
|
||||
int SEC = RTFAttribute.D_SECTION;
|
||||
int DOC = RTFAttribute.D_DOCUMENT;
|
||||
int PST = RTFAttribute.D_META;
|
||||
Boolean True = Boolean.valueOf(true);
|
||||
Boolean False = Boolean.valueOf(false);
|
||||
|
||||
a.addElement(new BooleanAttribute(CHR, StyleConstants.Italic, "i"));
|
||||
a.addElement(new BooleanAttribute(CHR, StyleConstants.Bold, "b"));
|
||||
a.addElement(new BooleanAttribute(CHR, StyleConstants.Underline, "ul"));
|
||||
a.addElement(NumericAttribute.NewTwips(PGF, StyleConstants.LeftIndent, "li",
|
||||
0f, 0));
|
||||
a.addElement(NumericAttribute.NewTwips(PGF, StyleConstants.RightIndent, "ri",
|
||||
0f, 0));
|
||||
a.addElement(NumericAttribute.NewTwips(PGF, StyleConstants.FirstLineIndent, "fi",
|
||||
0f, 0));
|
||||
|
||||
a.addElement(new AssertiveAttribute(PGF, StyleConstants.Alignment,
|
||||
"ql", StyleConstants.ALIGN_LEFT));
|
||||
a.addElement(new AssertiveAttribute(PGF, StyleConstants.Alignment,
|
||||
"qr", StyleConstants.ALIGN_RIGHT));
|
||||
a.addElement(new AssertiveAttribute(PGF, StyleConstants.Alignment,
|
||||
"qc", StyleConstants.ALIGN_CENTER));
|
||||
a.addElement(new AssertiveAttribute(PGF, StyleConstants.Alignment,
|
||||
"qj", StyleConstants.ALIGN_JUSTIFIED));
|
||||
a.addElement(NumericAttribute.NewTwips(PGF, StyleConstants.SpaceAbove,
|
||||
"sa", 0));
|
||||
a.addElement(NumericAttribute.NewTwips(PGF, StyleConstants.SpaceBelow,
|
||||
"sb", 0));
|
||||
|
||||
a.addElement(new AssertiveAttribute(PST, RTFReader.TabAlignmentKey,
|
||||
"tqr", TabStop.ALIGN_RIGHT));
|
||||
a.addElement(new AssertiveAttribute(PST, RTFReader.TabAlignmentKey,
|
||||
"tqc", TabStop.ALIGN_CENTER));
|
||||
a.addElement(new AssertiveAttribute(PST, RTFReader.TabAlignmentKey,
|
||||
"tqdec", TabStop.ALIGN_DECIMAL));
|
||||
|
||||
|
||||
a.addElement(new AssertiveAttribute(PST, RTFReader.TabLeaderKey,
|
||||
"tldot", TabStop.LEAD_DOTS));
|
||||
a.addElement(new AssertiveAttribute(PST, RTFReader.TabLeaderKey,
|
||||
"tlhyph", TabStop.LEAD_HYPHENS));
|
||||
a.addElement(new AssertiveAttribute(PST, RTFReader.TabLeaderKey,
|
||||
"tlul", TabStop.LEAD_UNDERLINE));
|
||||
a.addElement(new AssertiveAttribute(PST, RTFReader.TabLeaderKey,
|
||||
"tlth", TabStop.LEAD_THICKLINE));
|
||||
a.addElement(new AssertiveAttribute(PST, RTFReader.TabLeaderKey,
|
||||
"tleq", TabStop.LEAD_EQUALS));
|
||||
|
||||
/* The following aren't actually recognized by Swing */
|
||||
a.addElement(new BooleanAttribute(CHR, Constants.Caps, "caps"));
|
||||
a.addElement(new BooleanAttribute(CHR, Constants.Outline, "outl"));
|
||||
a.addElement(new BooleanAttribute(CHR, Constants.SmallCaps, "scaps"));
|
||||
a.addElement(new BooleanAttribute(CHR, Constants.Shadow, "shad"));
|
||||
a.addElement(new BooleanAttribute(CHR, Constants.Hidden, "v"));
|
||||
a.addElement(new BooleanAttribute(CHR, Constants.Strikethrough,
|
||||
"strike"));
|
||||
a.addElement(new BooleanAttribute(CHR, Constants.Deleted,
|
||||
"deleted"));
|
||||
|
||||
|
||||
|
||||
a.addElement(new AssertiveAttribute(DOC, "saveformat", "defformat", "RTF"));
|
||||
a.addElement(new AssertiveAttribute(DOC, "landscape", "landscape"));
|
||||
|
||||
a.addElement(NumericAttribute.NewTwips(DOC, Constants.PaperWidth,
|
||||
"paperw", 12240));
|
||||
a.addElement(NumericAttribute.NewTwips(DOC, Constants.PaperHeight,
|
||||
"paperh", 15840));
|
||||
a.addElement(NumericAttribute.NewTwips(DOC, Constants.MarginLeft,
|
||||
"margl", 1800));
|
||||
a.addElement(NumericAttribute.NewTwips(DOC, Constants.MarginRight,
|
||||
"margr", 1800));
|
||||
a.addElement(NumericAttribute.NewTwips(DOC, Constants.MarginTop,
|
||||
"margt", 1440));
|
||||
a.addElement(NumericAttribute.NewTwips(DOC, Constants.MarginBottom,
|
||||
"margb", 1440));
|
||||
a.addElement(NumericAttribute.NewTwips(DOC, Constants.GutterWidth,
|
||||
"gutter", 0));
|
||||
|
||||
a.addElement(new AssertiveAttribute(PGF, Constants.WidowControl,
|
||||
"nowidctlpar", False));
|
||||
a.addElement(new AssertiveAttribute(PGF, Constants.WidowControl,
|
||||
"widctlpar", True));
|
||||
a.addElement(new AssertiveAttribute(DOC, Constants.WidowControl,
|
||||
"widowctrl", True));
|
||||
|
||||
|
||||
RTFAttribute[] attrs = new RTFAttribute[a.size()];
|
||||
a.copyInto(attrs);
|
||||
attributes = attrs;
|
||||
}
|
||||
|
||||
static Dictionary<String, RTFAttribute> attributesByKeyword()
|
||||
{
|
||||
Dictionary<String, RTFAttribute> d = new Hashtable<String, RTFAttribute>(attributes.length);
|
||||
|
||||
for (RTFAttribute attribute : attributes) {
|
||||
d.put(attribute.rtfName(), attribute);
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/************************************************************************/
|
||||
|
||||
static abstract class GenericAttribute
|
||||
{
|
||||
int domain;
|
||||
Object swingName;
|
||||
String rtfName;
|
||||
|
||||
protected GenericAttribute(int d,Object s, String r)
|
||||
{
|
||||
domain = d;
|
||||
swingName = s;
|
||||
rtfName = r;
|
||||
}
|
||||
|
||||
public int domain() { return domain; }
|
||||
public Object swingName() { return swingName; }
|
||||
public String rtfName() { return rtfName; }
|
||||
|
||||
abstract boolean set(MutableAttributeSet target);
|
||||
abstract boolean set(MutableAttributeSet target, int parameter);
|
||||
abstract boolean setDefault(MutableAttributeSet target);
|
||||
|
||||
public boolean write(AttributeSet source,
|
||||
RTFGenerator target,
|
||||
boolean force)
|
||||
throws IOException
|
||||
{
|
||||
return writeValue(source.getAttribute(swingName), target, force);
|
||||
}
|
||||
|
||||
public boolean writeValue(Object value, RTFGenerator target,
|
||||
boolean force)
|
||||
throws IOException
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static class BooleanAttribute
|
||||
extends GenericAttribute
|
||||
implements RTFAttribute
|
||||
{
|
||||
boolean rtfDefault;
|
||||
boolean swingDefault;
|
||||
|
||||
protected static final Boolean True = Boolean.valueOf(true);
|
||||
protected static final Boolean False = Boolean.valueOf(false);
|
||||
|
||||
public BooleanAttribute(int d, Object s,
|
||||
String r, boolean ds, boolean dr)
|
||||
{
|
||||
super(d, s, r);
|
||||
swingDefault = ds;
|
||||
rtfDefault = dr;
|
||||
}
|
||||
|
||||
public BooleanAttribute(int d, Object s, String r)
|
||||
{
|
||||
super(d, s, r);
|
||||
|
||||
swingDefault = false;
|
||||
rtfDefault = false;
|
||||
}
|
||||
|
||||
public boolean set(MutableAttributeSet target)
|
||||
{
|
||||
/* TODO: There's some ambiguity about whether this should
|
||||
*set* or *toggle* the attribute. */
|
||||
target.addAttribute(swingName, True);
|
||||
|
||||
return true; /* true indicates we were successful */
|
||||
}
|
||||
|
||||
public boolean set(MutableAttributeSet target, int parameter)
|
||||
{
|
||||
/* See above note in the case that parameter==1 */
|
||||
Boolean value = ( parameter != 0 ? True : False );
|
||||
|
||||
target.addAttribute(swingName, value);
|
||||
|
||||
return true; /* true indicates we were successful */
|
||||
}
|
||||
|
||||
public boolean setDefault(MutableAttributeSet target)
|
||||
{
|
||||
if (swingDefault != rtfDefault ||
|
||||
( target.getAttribute(swingName) != null ) )
|
||||
target.addAttribute(swingName, Boolean.valueOf(rtfDefault));
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean writeValue(Object o_value,
|
||||
RTFGenerator target,
|
||||
boolean force)
|
||||
throws IOException
|
||||
{
|
||||
Boolean val;
|
||||
|
||||
if (o_value == null)
|
||||
val = Boolean.valueOf(swingDefault);
|
||||
else
|
||||
val = (Boolean)o_value;
|
||||
|
||||
if (force || (val.booleanValue() != rtfDefault)) {
|
||||
if (val.booleanValue()) {
|
||||
target.writeControlWord(rtfName);
|
||||
} else {
|
||||
target.writeControlWord(rtfName, 0);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class AssertiveAttribute
|
||||
extends GenericAttribute
|
||||
implements RTFAttribute
|
||||
{
|
||||
Object swingValue;
|
||||
|
||||
public AssertiveAttribute(int d, Object s, String r)
|
||||
{
|
||||
super(d, s, r);
|
||||
swingValue = Boolean.valueOf(true);
|
||||
}
|
||||
|
||||
public AssertiveAttribute(int d, Object s, String r, Object v)
|
||||
{
|
||||
super(d, s, r);
|
||||
swingValue = v;
|
||||
}
|
||||
|
||||
public AssertiveAttribute(int d, Object s, String r, int v)
|
||||
{
|
||||
super(d, s, r);
|
||||
swingValue = Integer.valueOf(v);
|
||||
}
|
||||
|
||||
public boolean set(MutableAttributeSet target)
|
||||
{
|
||||
if (swingValue == null)
|
||||
target.removeAttribute(swingName);
|
||||
else
|
||||
target.addAttribute(swingName, swingValue);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean set(MutableAttributeSet target, int parameter)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean setDefault(MutableAttributeSet target)
|
||||
{
|
||||
target.removeAttribute(swingName);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean writeValue(Object value,
|
||||
RTFGenerator target,
|
||||
boolean force)
|
||||
throws IOException
|
||||
{
|
||||
if (value == null) {
|
||||
return ! force;
|
||||
}
|
||||
|
||||
if (value.equals(swingValue)) {
|
||||
target.writeControlWord(rtfName);
|
||||
return true;
|
||||
}
|
||||
|
||||
return ! force;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class NumericAttribute
|
||||
extends GenericAttribute
|
||||
implements RTFAttribute
|
||||
{
|
||||
int rtfDefault;
|
||||
Number swingDefault;
|
||||
float scale;
|
||||
|
||||
protected NumericAttribute(int d, Object s, String r)
|
||||
{
|
||||
super(d, s, r);
|
||||
rtfDefault = 0;
|
||||
swingDefault = null;
|
||||
scale = 1f;
|
||||
}
|
||||
|
||||
public NumericAttribute(int d, Object s,
|
||||
String r, int ds, int dr)
|
||||
{
|
||||
this(d, s, r, Integer.valueOf(ds), dr, 1f);
|
||||
}
|
||||
|
||||
public NumericAttribute(int d, Object s,
|
||||
String r, Number ds, int dr, float sc)
|
||||
{
|
||||
super(d, s, r);
|
||||
swingDefault = ds;
|
||||
rtfDefault = dr;
|
||||
scale = sc;
|
||||
}
|
||||
|
||||
public static NumericAttribute NewTwips(int d, Object s, String r,
|
||||
float ds, int dr)
|
||||
{
|
||||
return new NumericAttribute(d, s, r, new Float(ds), dr, 20f);
|
||||
}
|
||||
|
||||
public static NumericAttribute NewTwips(int d, Object s, String r,
|
||||
int dr)
|
||||
{
|
||||
return new NumericAttribute(d, s, r, null, dr, 20f);
|
||||
}
|
||||
|
||||
public boolean set(MutableAttributeSet target)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean set(MutableAttributeSet target, int parameter)
|
||||
{
|
||||
Number swingValue;
|
||||
|
||||
if (scale == 1f)
|
||||
swingValue = Integer.valueOf(parameter);
|
||||
else
|
||||
swingValue = new Float(parameter / scale);
|
||||
target.addAttribute(swingName, swingValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean setDefault(MutableAttributeSet target)
|
||||
{
|
||||
Number old = (Number)target.getAttribute(swingName);
|
||||
if (old == null)
|
||||
old = swingDefault;
|
||||
if (old != null && (
|
||||
(scale == 1f && old.intValue() == rtfDefault) ||
|
||||
(Math.round(old.floatValue() * scale) == rtfDefault)
|
||||
))
|
||||
return true;
|
||||
set(target, rtfDefault);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean writeValue(Object o_value,
|
||||
RTFGenerator target,
|
||||
boolean force)
|
||||
throws IOException
|
||||
{
|
||||
Number value = (Number)o_value;
|
||||
if (value == null)
|
||||
value = swingDefault;
|
||||
if (value == null) {
|
||||
/* TODO: What is the proper behavior if the Swing object does
|
||||
not specify a value, and we don't know its default value?
|
||||
Currently we pretend that the RTF default value is
|
||||
equivalent (probably a workable assumption) */
|
||||
return true;
|
||||
}
|
||||
int int_value = Math.round(value.floatValue() * scale);
|
||||
if (force || (int_value != rtfDefault))
|
||||
target.writeControlWord(rtfName, int_value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
155
jdkSrc/jdk8/javax/swing/text/rtf/RTFEditorKit.java
Normal file
155
jdkSrc/jdk8/javax/swing/text/rtf/RTFEditorKit.java
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.text.rtf;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.text.*;
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* This is the default implementation of RTF editing
|
||||
* functionality. The RTF support was not written by the
|
||||
* Swing team. In the future we hope to improve the support
|
||||
* provided.
|
||||
*
|
||||
* @author Timothy Prinzing (of this class, not the package!)
|
||||
*/
|
||||
public class RTFEditorKit extends StyledEditorKit {
|
||||
|
||||
/**
|
||||
* Constructs an RTFEditorKit.
|
||||
*/
|
||||
public RTFEditorKit() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the MIME type of the data that this
|
||||
* kit represents support for. This kit supports
|
||||
* the type <code>text/rtf</code>.
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
public String getContentType() {
|
||||
return "text/rtf";
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert content from the given stream which is expected
|
||||
* to be in a format appropriate for this kind of content
|
||||
* handler.
|
||||
*
|
||||
* @param in The stream to read from
|
||||
* @param doc The destination for the insertion.
|
||||
* @param pos The location in the document to place the
|
||||
* content.
|
||||
* @exception IOException on any I/O error
|
||||
* @exception BadLocationException if pos represents an invalid
|
||||
* location within the document.
|
||||
*/
|
||||
public void read(InputStream in, Document doc, int pos) throws IOException, BadLocationException {
|
||||
|
||||
if (doc instanceof StyledDocument) {
|
||||
// PENDING(prinz) this needs to be fixed to
|
||||
// insert to the given position.
|
||||
RTFReader rdr = new RTFReader((StyledDocument) doc);
|
||||
rdr.readFromStream(in);
|
||||
rdr.close();
|
||||
} else {
|
||||
// treat as text/plain
|
||||
super.read(in, doc, pos);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write content from a document to the given stream
|
||||
* in a format appropriate for this kind of content handler.
|
||||
*
|
||||
* @param out The stream to write to
|
||||
* @param doc The source for the write.
|
||||
* @param pos The location in the document to fetch the
|
||||
* content.
|
||||
* @param len The amount to write out.
|
||||
* @exception IOException on any I/O error
|
||||
* @exception BadLocationException if pos represents an invalid
|
||||
* location within the document.
|
||||
*/
|
||||
public void write(OutputStream out, Document doc, int pos, int len)
|
||||
throws IOException, BadLocationException {
|
||||
|
||||
// PENDING(prinz) this needs to be fixed to
|
||||
// use the given document range.
|
||||
RTFGenerator.writeDocument(doc, out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert content from the given stream, which will be
|
||||
* treated as plain text.
|
||||
*
|
||||
* @param in The stream to read from
|
||||
* @param doc The destination for the insertion.
|
||||
* @param pos The location in the document to place the
|
||||
* content.
|
||||
* @exception IOException on any I/O error
|
||||
* @exception BadLocationException if pos represents an invalid
|
||||
* location within the document.
|
||||
*/
|
||||
public void read(Reader in, Document doc, int pos)
|
||||
throws IOException, BadLocationException {
|
||||
|
||||
if (doc instanceof StyledDocument) {
|
||||
RTFReader rdr = new RTFReader((StyledDocument) doc);
|
||||
rdr.readFromReader(in);
|
||||
rdr.close();
|
||||
} else {
|
||||
// treat as text/plain
|
||||
super.read(in, doc, pos);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write content from a document to the given stream
|
||||
* as plain text.
|
||||
*
|
||||
* @param out The stream to write to
|
||||
* @param doc The source for the write.
|
||||
* @param pos The location in the document to fetch the
|
||||
* content.
|
||||
* @param len The amount to write out.
|
||||
* @exception IOException on any I/O error
|
||||
* @exception BadLocationException if pos represents an invalid
|
||||
* location within the document.
|
||||
*/
|
||||
public void write(Writer out, Document doc, int pos, int len)
|
||||
throws IOException, BadLocationException {
|
||||
|
||||
throw new IOException("RTF is an 8-bit format");
|
||||
}
|
||||
|
||||
}
|
||||
1001
jdkSrc/jdk8/javax/swing/text/rtf/RTFGenerator.java
Normal file
1001
jdkSrc/jdk8/javax/swing/text/rtf/RTFGenerator.java
Normal file
File diff suppressed because it is too large
Load Diff
362
jdkSrc/jdk8/javax/swing/text/rtf/RTFParser.java
Normal file
362
jdkSrc/jdk8/javax/swing/text/rtf/RTFParser.java
Normal file
@@ -0,0 +1,362 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.swing.text.rtf;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.*;
|
||||
|
||||
/**
|
||||
* <b>RTFParser</b> is a subclass of <b>AbstractFilter</b> which understands basic RTF syntax
|
||||
* and passes a stream of control words, text, and begin/end group
|
||||
* indications to its subclass.
|
||||
*
|
||||
* Normally programmers will only use <b>RTFFilter</b>, a subclass of this class that knows what to
|
||||
* do with the tokens this class parses.
|
||||
*
|
||||
* @see AbstractFilter
|
||||
* @see RTFFilter
|
||||
*/
|
||||
abstract class RTFParser extends AbstractFilter
|
||||
{
|
||||
/** The current RTF group nesting level. */
|
||||
public int level;
|
||||
|
||||
private int state;
|
||||
private StringBuffer currentCharacters;
|
||||
private String pendingKeyword; // where keywords go while we
|
||||
// read their parameters
|
||||
private int pendingCharacter; // for the \'xx construct
|
||||
|
||||
private long binaryBytesLeft; // in a \bin blob?
|
||||
ByteArrayOutputStream binaryBuf;
|
||||
private boolean[] savedSpecials;
|
||||
|
||||
/** A stream to which to write warnings and debugging information
|
||||
* while parsing. This is set to <code>System.out</code> to log
|
||||
* any anomalous information to stdout. */
|
||||
protected PrintStream warnings;
|
||||
|
||||
// value for the 'state' variable
|
||||
private final int S_text = 0; // reading random text
|
||||
private final int S_backslashed = 1; // read a backslash, waiting for next
|
||||
private final int S_token = 2; // reading a multicharacter token
|
||||
private final int S_parameter = 3; // reading a token's parameter
|
||||
|
||||
private final int S_aftertick = 4; // after reading \'
|
||||
private final int S_aftertickc = 5; // after reading \'x
|
||||
|
||||
private final int S_inblob = 6; // in a \bin blob
|
||||
|
||||
/** Implemented by subclasses to interpret a parameter-less RTF keyword.
|
||||
* The keyword is passed without the leading '/' or any delimiting
|
||||
* whitespace. */
|
||||
public abstract boolean handleKeyword(String keyword);
|
||||
/** Implemented by subclasses to interpret a keyword with a parameter.
|
||||
* @param keyword The keyword, as with <code>handleKeyword(String)</code>.
|
||||
* @param parameter The parameter following the keyword. */
|
||||
public abstract boolean handleKeyword(String keyword, int parameter);
|
||||
/** Implemented by subclasses to interpret text from the RTF stream. */
|
||||
public abstract void handleText(String text);
|
||||
public void handleText(char ch)
|
||||
{ handleText(String.valueOf(ch)); }
|
||||
/** Implemented by subclasses to handle the contents of the \bin keyword. */
|
||||
public abstract void handleBinaryBlob(byte[] data);
|
||||
/** Implemented by subclasses to react to an increase
|
||||
* in the nesting level. */
|
||||
public abstract void begingroup();
|
||||
/** Implemented by subclasses to react to the end of a group. */
|
||||
public abstract void endgroup();
|
||||
|
||||
// table of non-text characters in rtf
|
||||
static final boolean rtfSpecialsTable[];
|
||||
static {
|
||||
rtfSpecialsTable = noSpecialsTable.clone();
|
||||
rtfSpecialsTable['\n'] = true;
|
||||
rtfSpecialsTable['\r'] = true;
|
||||
rtfSpecialsTable['{'] = true;
|
||||
rtfSpecialsTable['}'] = true;
|
||||
rtfSpecialsTable['\\'] = true;
|
||||
}
|
||||
|
||||
public RTFParser()
|
||||
{
|
||||
currentCharacters = new StringBuffer();
|
||||
state = S_text;
|
||||
pendingKeyword = null;
|
||||
level = 0;
|
||||
//warnings = System.out;
|
||||
|
||||
specialsTable = rtfSpecialsTable;
|
||||
}
|
||||
|
||||
// TODO: Handle wrapup at end of file correctly.
|
||||
|
||||
public void writeSpecial(int b)
|
||||
throws IOException
|
||||
{
|
||||
write((char)b);
|
||||
}
|
||||
|
||||
protected void warning(String s) {
|
||||
if (warnings != null) {
|
||||
warnings.println(s);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(String s)
|
||||
throws IOException
|
||||
{
|
||||
if (state != S_text) {
|
||||
int index = 0;
|
||||
int length = s.length();
|
||||
while(index < length && state != S_text) {
|
||||
write(s.charAt(index));
|
||||
index ++;
|
||||
}
|
||||
|
||||
if(index >= length)
|
||||
return;
|
||||
|
||||
s = s.substring(index);
|
||||
}
|
||||
|
||||
if (currentCharacters.length() > 0)
|
||||
currentCharacters.append(s);
|
||||
else
|
||||
handleText(s);
|
||||
}
|
||||
|
||||
public void write(char ch)
|
||||
throws IOException
|
||||
{
|
||||
boolean ok;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case S_text:
|
||||
if (ch == '\n' || ch == '\r') {
|
||||
break; // unadorned newlines are ignored
|
||||
} else if (ch == '{') {
|
||||
if (currentCharacters.length() > 0) {
|
||||
handleText(currentCharacters.toString());
|
||||
currentCharacters = new StringBuffer();
|
||||
}
|
||||
level ++;
|
||||
begingroup();
|
||||
} else if(ch == '}') {
|
||||
if (currentCharacters.length() > 0) {
|
||||
handleText(currentCharacters.toString());
|
||||
currentCharacters = new StringBuffer();
|
||||
}
|
||||
if (level == 0)
|
||||
throw new IOException("Too many close-groups in RTF text");
|
||||
endgroup();
|
||||
level --;
|
||||
} else if(ch == '\\') {
|
||||
if (currentCharacters.length() > 0) {
|
||||
handleText(currentCharacters.toString());
|
||||
currentCharacters = new StringBuffer();
|
||||
}
|
||||
state = S_backslashed;
|
||||
} else {
|
||||
currentCharacters.append(ch);
|
||||
}
|
||||
break;
|
||||
case S_backslashed:
|
||||
if (ch == '\'') {
|
||||
state = S_aftertick;
|
||||
break;
|
||||
}
|
||||
if (!Character.isLetter(ch)) {
|
||||
char newstring[] = new char[1];
|
||||
newstring[0] = ch;
|
||||
if (!handleKeyword(new String(newstring))) {
|
||||
warning("Unknown keyword: " + newstring + " (" + (byte)ch + ")");
|
||||
}
|
||||
state = S_text;
|
||||
pendingKeyword = null;
|
||||
/* currentCharacters is already an empty stringBuffer */
|
||||
break;
|
||||
}
|
||||
|
||||
state = S_token;
|
||||
/* FALL THROUGH */
|
||||
case S_token:
|
||||
if (Character.isLetter(ch)) {
|
||||
currentCharacters.append(ch);
|
||||
} else {
|
||||
pendingKeyword = currentCharacters.toString();
|
||||
currentCharacters = new StringBuffer();
|
||||
|
||||
// Parameter following?
|
||||
if (Character.isDigit(ch) || (ch == '-')) {
|
||||
state = S_parameter;
|
||||
currentCharacters.append(ch);
|
||||
} else {
|
||||
ok = handleKeyword(pendingKeyword);
|
||||
if (!ok)
|
||||
warning("Unknown keyword: " + pendingKeyword);
|
||||
pendingKeyword = null;
|
||||
state = S_text;
|
||||
|
||||
// Non-space delimiters get included in the text
|
||||
if (!Character.isWhitespace(ch))
|
||||
write(ch);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case S_parameter:
|
||||
if (Character.isDigit(ch)) {
|
||||
currentCharacters.append(ch);
|
||||
} else {
|
||||
/* TODO: Test correct behavior of \bin keyword */
|
||||
|
||||
if (pendingKeyword.equals("bin")) { /* magic layer-breaking kwd */
|
||||
long parameter = 0L;
|
||||
try {
|
||||
parameter = Long.parseLong(currentCharacters.toString());
|
||||
} catch (NumberFormatException e) {
|
||||
warning("Illegal number format " + currentCharacters.toString()
|
||||
+ " in \bin tag");
|
||||
pendingKeyword = null;
|
||||
currentCharacters = new StringBuffer();
|
||||
state = S_text;
|
||||
// Delimiters here are interpreted as text too
|
||||
if (!Character.isWhitespace(ch))
|
||||
write(ch);
|
||||
break;
|
||||
}
|
||||
pendingKeyword = null;
|
||||
state = S_inblob;
|
||||
int maxBytes = 4 * 1024 * 1024;
|
||||
binaryBytesLeft = parameter;
|
||||
|
||||
if (binaryBytesLeft > maxBytes) {
|
||||
binaryBuf = new ByteArrayOutputStream(maxBytes);
|
||||
} else if (binaryBytesLeft < 0) {
|
||||
binaryBytesLeft = 0;
|
||||
binaryBuf = new ByteArrayOutputStream((int)binaryBytesLeft);
|
||||
} else {
|
||||
binaryBuf = new ByteArrayOutputStream((int) binaryBytesLeft);
|
||||
}
|
||||
savedSpecials = specialsTable;
|
||||
specialsTable = allSpecialsTable;
|
||||
break;
|
||||
}
|
||||
|
||||
int parameter = 0;
|
||||
try {
|
||||
parameter = Integer.parseInt(currentCharacters.toString());
|
||||
ok = handleKeyword(pendingKeyword, parameter);
|
||||
if (!ok) {
|
||||
warning("Unknown keyword: " + pendingKeyword +
|
||||
" (param " + currentCharacters + ")");
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
warning("Illegal number format " + currentCharacters.toString()
|
||||
+ " in " + pendingKeyword + " tag");
|
||||
}
|
||||
pendingKeyword = null;
|
||||
currentCharacters = new StringBuffer();
|
||||
state = S_text;
|
||||
|
||||
// Delimiters here are interpreted as text too
|
||||
if (!Character.isWhitespace(ch))
|
||||
write(ch);
|
||||
}
|
||||
break;
|
||||
case S_aftertick:
|
||||
if (Character.digit(ch, 16) == -1)
|
||||
state = S_text;
|
||||
else {
|
||||
pendingCharacter = Character.digit(ch, 16);
|
||||
state = S_aftertickc;
|
||||
}
|
||||
break;
|
||||
case S_aftertickc:
|
||||
state = S_text;
|
||||
if (Character.digit(ch, 16) != -1)
|
||||
{
|
||||
pendingCharacter = pendingCharacter * 16 + Character.digit(ch, 16);
|
||||
ch = translationTable[pendingCharacter];
|
||||
if (ch != 0)
|
||||
handleText(ch);
|
||||
}
|
||||
break;
|
||||
case S_inblob:
|
||||
if (binaryBytesLeft > 0) {
|
||||
binaryBuf.write(ch);
|
||||
binaryBytesLeft--;
|
||||
}
|
||||
if (binaryBytesLeft == 0) {
|
||||
state = S_text;
|
||||
specialsTable = savedSpecials;
|
||||
savedSpecials = null;
|
||||
handleBinaryBlob(binaryBuf.toByteArray());
|
||||
binaryBuf = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Flushes any buffered but not yet written characters.
|
||||
* Subclasses which override this method should call this
|
||||
* method <em>before</em> flushing
|
||||
* any of their own buffers. */
|
||||
public void flush()
|
||||
throws IOException
|
||||
{
|
||||
super.flush();
|
||||
|
||||
if (state == S_text && currentCharacters.length() > 0) {
|
||||
handleText(currentCharacters.toString());
|
||||
currentCharacters = new StringBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
/** Closes the parser. Currently, this simply does a <code>flush()</code>,
|
||||
* followed by some minimal consistency checks. */
|
||||
public void close()
|
||||
throws IOException
|
||||
{
|
||||
flush();
|
||||
|
||||
if (state != S_text || level > 0) {
|
||||
warning("Truncated RTF file.");
|
||||
|
||||
/* TODO: any sane way to handle termination in a non-S_text state? */
|
||||
/* probably not */
|
||||
|
||||
/* this will cause subclasses to behave more reasonably
|
||||
some of the time */
|
||||
while (level > 0) {
|
||||
endgroup();
|
||||
level --;
|
||||
}
|
||||
}
|
||||
|
||||
super.close();
|
||||
}
|
||||
|
||||
}
|
||||
1647
jdkSrc/jdk8/javax/swing/text/rtf/RTFReader.java
Normal file
1647
jdkSrc/jdk8/javax/swing/text/rtf/RTFReader.java
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user