feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View 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;
}

View 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";
}

View 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!");
}
}

View 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;
}

View 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;
}
}
}

View 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");
}
}

File diff suppressed because it is too large Load Diff

View 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();
}
}

File diff suppressed because it is too large Load Diff