All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fife.ui.rsyntaxtextarea.RtfGenerator Maven / Gradle / Ivy

The newest version!
/*
 * 07/28/2008
 *
 * RtfGenerator.java - Generates RTF via a simple Java API.
 * 
 * This library is distributed under a modified BSD license.  See the included
 * RSyntaxTextArea.License.txt file for details.
 */
package org.fife.ui.rsyntaxtextarea;

import java.awt.Color;
import java.awt.Font;
import java.awt.Toolkit;
import java.util.ArrayList;
import java.util.List;

import org.fife.ui.rtextarea.RTextArea;


/**
 * Generates RTF text via a simple Java API.

* * The following RTF features are supported: *

    *
  • Fonts *
  • Font sizes *
  • Foreground and background colors *
  • Bold, italic, and underline *
* * The RTF generated isn't really "optimized," but it will do, especially for * small amounts of text, such as what's common when copy-and-pasting. It * tries to be sufficient for the use case of copying syntax highlighted * code: *
    *
  • It assumes that tokens changing foreground color often is fairly * common. *
  • It assumes that background highlighting is fairly uncommon. *
* * @author Robert Futrell * @version 1.0 */ public class RtfGenerator { private List fontList; private List colorList; private StringBuilder document; private boolean lastWasControlWord; private int lastFontIndex; private int lastFGIndex; private boolean lastBold; private boolean lastItalic; private int lastFontSize; /** * Java2D assumes a 72 dpi screen resolution, but on Windows the screen * resolution is either 96 dpi or 120 dpi, depending on your font display * settings. This is an attempt to make the RTF generated match the * size of what's displayed in the RSyntaxTextArea. */ private int screenRes; /** * The default font size for RTF. This is point size, in half * points. */ private static final int DEFAULT_FONT_SIZE = 12;//24; /** * Constructor. */ public RtfGenerator() { fontList = new ArrayList(1); // Usually only 1. colorList = new ArrayList(1); // Usually only 1. document = new StringBuilder(); reset(); } /** * Adds a newline to the RTF document. * * @see #appendToDoc(String, Font, Color, Color) */ public void appendNewline() { document.append("\\par"); document.append('\n'); // Just for ease of reading RTF. lastWasControlWord = false; } /** * Appends styled text to the RTF document being generated. * * @param text The text to append. * @param f The font of the text. If this is null, the * default font is used. * @param fg The foreground of the text. If this is null, * the default foreground color is used. * @param bg The background color of the text. If this is * null, the default background color is used. * @see #appendNewline() */ public void appendToDoc(String text, Font f, Color fg, Color bg) { appendToDoc(text, f, fg, bg, false); } /** * Appends styled text to the RTF document being generated. * * @param text The text to append. * @param f The font of the text. If this is null, the * default font is used. * @param bg The background color of the text. If this is * null, the default background color is used. * @param underline Whether the text should be underlined. * @see #appendNewline() */ public void appendToDocNoFG(String text, Font f, Color bg, boolean underline) { appendToDoc(text, f, null, bg, underline, false); } /** * Appends styled text to the RTF document being generated. * * @param text The text to append. * @param f The font of the text. If this is null, the * default font is used. * @param fg The foreground of the text. If this is null, * the default foreground color is used. * @param bg The background color of the text. If this is * null, the default background color is used. * @param underline Whether the text should be underlined. * @see #appendNewline() */ public void appendToDoc(String text, Font f, Color fg, Color bg, boolean underline) { appendToDoc(text, f, fg, bg, underline, true); } /** * Appends styled text to the RTF document being generated. * * @param text The text to append. * @param f The font of the text. If this is null, the * default font is used. * @param fg The foreground of the text. If this is null, * the default foreground color is used. * @param bg The background color of the text. If this is * null, the default background color is used. * @param underline Whether the text should be underlined. * @param setFG Whether the foreground specified by fg should * be honored (if it is non-null). * @see #appendNewline() */ public void appendToDoc(String text, Font f, Color fg, Color bg, boolean underline, boolean setFG) { if (text!=null) { // Set font to use, if different from last addition. int fontIndex = f==null ? 0 : (getFontIndex(fontList, f)+1); if (fontIndex!=lastFontIndex) { document.append("\\f").append(fontIndex); lastFontIndex = fontIndex; lastWasControlWord = true; } // Set styles to use. if (f!=null) { int fontSize = fixFontSize(f.getSize2D()*2); // Half points! if (fontSize!=lastFontSize) { document.append("\\fs").append(fontSize); lastFontSize = fontSize; lastWasControlWord = true; } if (f.isBold()!=lastBold) { document.append(lastBold ? "\\b0" : "\\b"); lastBold = !lastBold; lastWasControlWord = true; } if (f.isItalic()!=lastItalic) { document.append(lastItalic ? "\\i0" : "\\i"); lastItalic = !lastItalic; lastWasControlWord = true; } } else { // No font specified - assume neither bold nor italic. if (lastFontSize!=DEFAULT_FONT_SIZE) { document.append("\\fs").append(DEFAULT_FONT_SIZE); lastFontSize = DEFAULT_FONT_SIZE; lastWasControlWord = true; } if (lastBold) { document.append("\\b0"); lastBold = false; lastWasControlWord = true; } if (lastItalic) { document.append("\\i0"); lastItalic = false; lastWasControlWord = true; } } if (underline) { document.append("\\ul"); lastWasControlWord = true; } // Set the foreground color. if (setFG) { int fgIndex = 0; if (fg!=null) { // null => fg color index 0 fgIndex = getColorIndex(colorList, fg)+1; } if (fgIndex!=lastFGIndex) { document.append("\\cf").append(fgIndex); lastFGIndex = fgIndex; lastWasControlWord = true; } } // Set the background color. if (bg!=null) { int pos = getColorIndex(colorList, bg); document.append("\\highlight").append(pos+1); lastWasControlWord = true; } if (lastWasControlWord) { document.append(' '); // Delimiter lastWasControlWord = false; } escapeAndAdd(document, text); // Reset everything that was set for this text fragment. if (bg!=null) { document.append("\\highlight0"); lastWasControlWord = true; } if (underline) { document.append("\\ul0"); lastWasControlWord = true; } } } /** * Appends some text to a buffer, with special care taken for special * characters as defined by the RTF spec: * *
    *
  • All tab characters are replaced with the string * "\tab" *
  • '\', '{' and '}' are changed to "\\", "\{" and "\}" *
* * @param text The text to append (with tab chars substituted). * @param sb The buffer to append to. */ private final void escapeAndAdd(StringBuilder sb, String text) { int count = text.length(); for (int i=0; i * * Java2D assumes 72 dpi. On systems with larger dpi (Windows, GTK, etc.), * font rendering will appear too small if we simply return a Java "Font" * object's getSize() value. We need to adjust it for the screen * resolution. * * @param pointSize A Java Font's point size, as returned from * getSize2D(). * @return The font point size, adjusted for the current screen resolution. * This will allow other applications to render fonts the same * size as they appear in the Java application. */ private int fixFontSize(float pointSize) { if (screenRes!=72) { // Java2D assumes 72 dpi pointSize = Math.round(pointSize*72f/screenRes); } return (int)pointSize; } /** * Returns the index of the specified item in a list. If the item * is not in the list, it is added, and its new index is returned. * * @param list The list (possibly) containing the item. * @param item The item to get the index of. * @return The index of the item. */ private static int getColorIndex(List list, Color item) { int pos = list.indexOf(item); if (pos==-1) { list.add(item); pos = list.size()-1; } return pos; } private String getColorTableRtf() { // Example: // "{\\colortbl ;\\red255\\green0\\blue0;\\red0\\green0\\blue255; }" StringBuilder sb = new StringBuilder(); sb.append("{\\colortbl ;"); for (Color c : colorList) { sb.append("\\red").append(c.getRed()); sb.append("\\green").append(c.getGreen()); sb.append("\\blue").append(c.getBlue()); sb.append(';'); } sb.append("}"); return sb.toString(); } /** * Returns the index of the specified font in a list of fonts. This * method only checks for a font by its family name; its attributes such * as bold and italic are ignored.

* * If the font is not in the list, it is added, and its new index is * returned. * * @param list The list (possibly) containing the font. * @param font The font to get the index of. * @return The index of the font. */ private static int getFontIndex(List list, Font font) { String fontName = font.getFamily(); for (int i=0; iString. */ public String getRtf() { StringBuilder sb = new StringBuilder(); sb.append("{"); // Header sb.append("\\rtf1\\ansi\\ansicpg1252"); sb.append("\\deff0"); // First font in font table is the default sb.append("\\deflang1033"); sb.append("\\viewkind4"); // "Normal" view sb.append("\\uc\\pard\\f0"); sb.append("\\fs20"); // Font size in half-points (default 24) sb.append(getFontTableRtf()).append('\n'); sb.append(getColorTableRtf()).append('\n'); // Content sb.append(document); sb.append("}"); //System.err.println("*** " + sb.length()); return sb.toString(); } /** * Resets this generator. All document information and content is * cleared. */ public void reset() { fontList.clear(); colorList.clear(); document.setLength(0); lastWasControlWord = false; lastFontIndex = 0; lastFGIndex = 0; lastBold = false; lastItalic = false; lastFontSize = DEFAULT_FONT_SIZE; screenRes = Toolkit.getDefaultToolkit().getScreenResolution(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy