home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 2000 March / pcp161a.iso / handson / files / copyjava.exe / com / sun / java / swing / text / rtf / RTFGenerator.class (.txt) < prev    next >
Encoding:
Java Class File  |  1998-02-26  |  14.8 KB  |  782 lines

  1. package com.sun.java.swing.text.rtf;
  2.  
  3. import com.sun.java.swing.text.AttributeSet;
  4. import com.sun.java.swing.text.BadLocationException;
  5. import com.sun.java.swing.text.Document;
  6. import com.sun.java.swing.text.Element;
  7. import com.sun.java.swing.text.MutableAttributeSet;
  8. import com.sun.java.swing.text.Segment;
  9. import com.sun.java.swing.text.SimpleAttributeSet;
  10. import com.sun.java.swing.text.Style;
  11. import com.sun.java.swing.text.StyleConstants;
  12. import com.sun.java.swing.text.TabStop;
  13. import java.awt.Color;
  14. import java.io.IOException;
  15. import java.io.OutputStream;
  16. import java.util.Dictionary;
  17. import java.util.Enumeration;
  18. import java.util.Hashtable;
  19. import java.util.Vector;
  20.  
  21. class RTFGenerator {
  22.    Dictionary colorTable = new Hashtable();
  23.    int colorCount;
  24.    Dictionary fontTable;
  25.    int fontCount;
  26.    Dictionary styleTable;
  27.    int styleCount;
  28.    OutputStream outputStream;
  29.    boolean afterKeyword;
  30.    MutableAttributeSet outputAttributes;
  31.    int unicodeCount;
  32.    private Segment workingSegment;
  33.    int[] outputConversion;
  34.    public static final Color defaultRTFColor;
  35.    public static final float defaultFontSize = 12.0F;
  36.    public static final String defaultFontFamily = "Helvetica";
  37.    protected static Integer One;
  38.    protected static Integer Zero;
  39.    protected static Boolean False;
  40.    protected static Float ZeroPointZero;
  41.    private static Object MagicToken;
  42.    protected static CharacterKeywordPair[] textKeywords;
  43.    static final char[] hexdigits;
  44.  
  45.    public static void writeDocument(Document var0, OutputStream var1) throws IOException {
  46.       RTFGenerator var2 = new RTFGenerator(var1);
  47.       Element var3 = var0.getDefaultRootElement();
  48.       var2.examineElement(var3);
  49.       var2.writeRTFHeader();
  50.       var2.writeDocumentProperties(var0);
  51.       int var4 = var3.getElementCount();
  52.  
  53.       for(int var5 = 0; var5 < var4; ++var5) {
  54.          var2.writeParagraphElement(var3.getElement(var5));
  55.       }
  56.  
  57.       var2.writeRTFTrailer();
  58.    }
  59.  
  60.    public RTFGenerator(OutputStream var1) {
  61.       this.colorTable.put(defaultRTFColor, new Integer(0));
  62.       this.colorCount = 1;
  63.       this.fontTable = new Hashtable();
  64.       this.fontCount = 0;
  65.       this.styleTable = new Hashtable();
  66.       this.styleCount = 0;
  67.       this.workingSegment = new Segment();
  68.       this.outputStream = var1;
  69.       this.unicodeCount = 1;
  70.    }
  71.  
  72.    public void examineElement(Element var1) {
  73.       AttributeSet var2 = var1.getAttributes();
  74.       this.tallyStyles(var2);
  75.       if (var2 != null) {
  76.          Color var4 = StyleConstants.getForeground(var2);
  77.          if (var4 != null && this.colorTable.get(var4) == null) {
  78.             this.colorTable.put(var4, new Integer(this.colorCount));
  79.             ++this.colorCount;
  80.          }
  81.  
  82.          Object var5 = var2.getAttribute(StyleConstants.Background);
  83.          if (var5 != null && this.colorTable.get(var5) == null) {
  84.             this.colorTable.put(var5, new Integer(this.colorCount));
  85.             ++this.colorCount;
  86.          }
  87.  
  88.          String var3 = StyleConstants.getFontFamily(var2);
  89.          if (var3 == null) {
  90.             var3 = "Helvetica";
  91.          }
  92.  
  93.          if (var3 != null && this.fontTable.get(var3) == null) {
  94.             this.fontTable.put(var3, new Integer(this.fontCount));
  95.             ++this.fontCount;
  96.          }
  97.       }
  98.  
  99.       int var6 = var1.getElementCount();
  100.  
  101.       for(int var7 = 0; var7 < var6; ++var7) {
  102.          this.examineElement(var1.getElement(var7));
  103.       }
  104.  
  105.    }
  106.  
  107.    private void tallyStyles(AttributeSet var1) {
  108.       for(; var1 != null; var1 = var1.getResolveParent()) {
  109.          if (var1 instanceof Style) {
  110.             Integer var2 = (Integer)this.styleTable.get(var1);
  111.             if (var2 == null) {
  112.                ++this.styleCount;
  113.                var2 = new Integer(this.styleCount);
  114.                this.styleTable.put(var1, var2);
  115.             }
  116.          }
  117.       }
  118.  
  119.    }
  120.  
  121.    private Style findStyle(AttributeSet var1) {
  122.       for(; var1 != null; var1 = var1.getResolveParent()) {
  123.          if (var1 instanceof Style) {
  124.             Object var2 = this.styleTable.get(var1);
  125.             if (var2 != null) {
  126.                return (Style)var1;
  127.             }
  128.          }
  129.       }
  130.  
  131.       return null;
  132.    }
  133.  
  134.    private Integer findStyleNumber(AttributeSet var1, String var2) {
  135.       for(; var1 != null; var1 = var1.getResolveParent()) {
  136.          if (var1 instanceof Style) {
  137.             Integer var3 = (Integer)this.styleTable.get(var1);
  138.             if (var3 != null && (var2 == null || var2.equals(((Style)var1).getAttribute("style:type")))) {
  139.                return var3;
  140.             }
  141.          }
  142.       }
  143.  
  144.       return null;
  145.    }
  146.  
  147.    private static Object attrDiff(MutableAttributeSet var0, AttributeSet var1, Object var2, Object var3) {
  148.       Object var4 = var0.getAttribute(var2);
  149.       Object var5 = var1.getAttribute(var2);
  150.       if (var5 == var4) {
  151.          return null;
  152.       } else if (var5 == null) {
  153.          var0.removeAttribute(var2);
  154.          return var3 != null && !var3.equals(var4) ? var3 : null;
  155.       } else if (var4 != null && equalArraysOK(var4, var5)) {
  156.          return null;
  157.       } else {
  158.          var0.addAttribute(var2, var5);
  159.          return var5;
  160.       }
  161.    }
  162.  
  163.    private static boolean equalArraysOK(Object var0, Object var1) {
  164.       if (var0 == var1) {
  165.          return true;
  166.       } else if (var0 != null && var1 != null) {
  167.          if (var0.equals(var1)) {
  168.             return true;
  169.          } else if (var0.getClass().isArray() && var1.getClass().isArray()) {
  170.             Object[] var2 = var0;
  171.             Object[] var3 = var1;
  172.             if (var2.length != var3.length) {
  173.                return false;
  174.             } else {
  175.                int var5 = var2.length;
  176.  
  177.                for(int var4 = 0; var4 < var5; ++var4) {
  178.                   if (!equalArraysOK(var2[var4], var3[var4])) {
  179.                      return false;
  180.                   }
  181.                }
  182.  
  183.                return true;
  184.             }
  185.          } else {
  186.             return false;
  187.          }
  188.       } else {
  189.          return false;
  190.       }
  191.    }
  192.  
  193.    public void writeLineBreak() throws IOException {
  194.       this.writeRawString("\n");
  195.       this.afterKeyword = false;
  196.    }
  197.  
  198.    public void writeRTFHeader() throws IOException {
  199.       this.writeBegingroup();
  200.       this.writeControlWord("rtf", 1);
  201.       this.writeControlWord("ansi");
  202.       this.outputConversion = outputConversionForName("ansi");
  203.       this.writeLineBreak();
  204.       String[] var2 = new String[this.fontCount];
  205.  
  206.       String var4;
  207.       Integer var5;
  208.       for(Enumeration var3 = this.fontTable.keys(); var3.hasMoreElements(); var2[var5] = var4) {
  209.          var4 = (String)var3.nextElement();
  210.          var5 = (Integer)this.fontTable.get(var4);
  211.       }
  212.  
  213.       this.writeBegingroup();
  214.       this.writeControlWord("fonttbl");
  215.  
  216.       for(int var1 = 0; var1 < this.fontCount; ++var1) {
  217.          this.writeControlWord("f", var1);
  218.          this.writeControlWord("fnil");
  219.          this.writeText(var2[var1]);
  220.          this.writeText(";");
  221.       }
  222.  
  223.       this.writeEndgroup();
  224.       this.writeLineBreak();
  225.       if (this.colorCount > 1) {
  226.          Color[] var15 = new Color[this.colorCount];
  227.  
  228.          Color var7;
  229.          Integer var8;
  230.          for(Enumeration var6 = this.colorTable.keys(); var6.hasMoreElements(); var15[var8] = var7) {
  231.             var7 = (Color)var6.nextElement();
  232.             var8 = (Integer)this.colorTable.get(var7);
  233.          }
  234.  
  235.          this.writeBegingroup();
  236.          this.writeControlWord("colortbl");
  237.  
  238.          for(int var14 = 0; var14 < this.colorCount; ++var14) {
  239.             var7 = var15[var14];
  240.             if (var7 != null) {
  241.                this.writeControlWord("red", var7.getRed());
  242.                this.writeControlWord("green", var7.getGreen());
  243.                this.writeControlWord("blue", var7.getBlue());
  244.             }
  245.  
  246.             this.writeRawString(";");
  247.          }
  248.  
  249.          this.writeEndgroup();
  250.          this.writeLineBreak();
  251.       }
  252.  
  253.       if (this.styleCount > 1) {
  254.          this.writeBegingroup();
  255.          this.writeControlWord("stylesheet");
  256.          Enumeration var16 = this.styleTable.keys();
  257.  
  258.          while(var16.hasMoreElements()) {
  259.             Style var17 = (Style)var16.nextElement();
  260.             int var19 = (Integer)this.styleTable.get(var17);
  261.             this.writeBegingroup();
  262.             String var20 = (String)var17.getAttribute("style:type");
  263.             if (var20 == null) {
  264.                var20 = "paragraph";
  265.             }
  266.  
  267.             if (var20.equals("character")) {
  268.                this.writeControlWord("*");
  269.                this.writeControlWord("cs", var19);
  270.             } else if (var20.equals("section")) {
  271.                this.writeControlWord("*");
  272.                this.writeControlWord("ds", var19);
  273.             } else {
  274.                this.writeControlWord("s", var19);
  275.             }
  276.  
  277.             AttributeSet var9 = var17.getResolveParent();
  278.             SimpleAttributeSet var10;
  279.             if (var9 == null) {
  280.                var10 = new SimpleAttributeSet();
  281.             } else {
  282.                var10 = new SimpleAttributeSet(var9);
  283.             }
  284.  
  285.             this.updateSectionAttributes(var10, var17, false);
  286.             this.updateParagraphAttributes(var10, var17, false);
  287.             this.updateCharacterAttributes(var10, var17, false);
  288.             var9 = var17.getResolveParent();
  289.             if (var9 != null && var9 instanceof Style) {
  290.                Integer var11 = (Integer)this.styleTable.get(var9);
  291.                if (var11 != null) {
  292.                   this.writeControlWord("sbasedon", var11);
  293.                }
  294.             }
  295.  
  296.             Style var22 = (Style)var17.getAttribute("style:nextStyle");
  297.             if (var22 != null) {
  298.                Integer var12 = (Integer)this.styleTable.get(var22);
  299.                if (var12 != null) {
  300.                   this.writeControlWord("snext", var12);
  301.                }
  302.             }
  303.  
  304.             Boolean var23 = (Boolean)var17.getAttribute("style:hidden");
  305.             if (var23 != null && var23) {
  306.                this.writeControlWord("shidden");
  307.             }
  308.  
  309.             Boolean var13 = (Boolean)var17.getAttribute("style:additive");
  310.             if (var13 != null && var13) {
  311.                this.writeControlWord("additive");
  312.             }
  313.  
  314.             this.writeText(var17.getName());
  315.             this.writeText(";");
  316.             this.writeEndgroup();
  317.          }
  318.  
  319.          this.writeEndgroup();
  320.          this.writeLineBreak();
  321.       }
  322.  
  323.       this.outputAttributes = new SimpleAttributeSet();
  324.    }
  325.  
  326.    void writeDocumentProperties(Document var1) throws IOException {
  327.       boolean var3 = false;
  328.  
  329.       for(int var2 = 0; var2 < RTFAttributes.attributes.length; ++var2) {
  330.          RTFAttribute var4 = RTFAttributes.attributes[var2];
  331.          if (var4.domain() == 3) {
  332.             Object var5 = var1.getProperty(var4.swingName());
  333.             boolean var6 = var4.writeValue(var5, this, false);
  334.             if (var6) {
  335.                var3 = true;
  336.             }
  337.          }
  338.       }
  339.  
  340.       if (var3) {
  341.          this.writeLineBreak();
  342.       }
  343.  
  344.    }
  345.  
  346.    public void writeRTFTrailer() throws IOException {
  347.       this.writeEndgroup();
  348.       this.writeLineBreak();
  349.    }
  350.  
  351.    protected void checkNumericControlWord(MutableAttributeSet var1, AttributeSet var2, Object var3, String var4, float var5, float var6) throws IOException {
  352.       Object var7;
  353.       if ((var7 = attrDiff(var1, var2, var3, MagicToken)) != null) {
  354.          float var8;
  355.          if (var7 == MagicToken) {
  356.             var8 = var5;
  357.          } else {
  358.             var8 = ((Number)var7).floatValue();
  359.          }
  360.  
  361.          this.writeControlWord(var4, Math.round(var8 * var6));
  362.       }
  363.  
  364.    }
  365.  
  366.    protected void checkControlWord(MutableAttributeSet var1, AttributeSet var2, RTFAttribute var3) throws IOException {
  367.       Object var4;
  368.       if ((var4 = attrDiff(var1, var2, var3.swingName(), MagicToken)) != null) {
  369.          if (var4 == MagicToken) {
  370.             var4 = null;
  371.          }
  372.  
  373.          var3.writeValue(var4, this, true);
  374.       }
  375.  
  376.    }
  377.  
  378.    protected void checkControlWords(MutableAttributeSet var1, AttributeSet var2, RTFAttribute[] var3, int var4) throws IOException {
  379.       for(RTFAttribute var7 : var3) {
  380.          if (var7.domain() == var4) {
  381.             this.checkControlWord(var1, var2, var7);
  382.          }
  383.       }
  384.  
  385.    }
  386.  
  387.    void updateSectionAttributes(MutableAttributeSet var1, AttributeSet var2, boolean var3) throws IOException {
  388.       if (var3) {
  389.          Object var4 = var1.getAttribute("sectionStyle");
  390.          Integer var5 = this.findStyleNumber(var2, "section");
  391.          if (var4 != var5) {
  392.             if (var4 != null) {
  393.                this.resetSectionAttributes(var1);
  394.             }
  395.  
  396.             if (var5 != null) {
  397.                this.writeControlWord("ds", (Integer)var5);
  398.                var1.addAttribute("sectionStyle", var5);
  399.             } else {
  400.                var1.removeAttribute("sectionStyle");
  401.             }
  402.          }
  403.       }
  404.  
  405.       this.checkControlWords(var1, var2, RTFAttributes.attributes, 2);
  406.    }
  407.  
  408.    protected void resetSectionAttributes(MutableAttributeSet var1) throws IOException {
  409.       this.writeControlWord("sectd");
  410.       int var3 = RTFAttributes.attributes.length;
  411.  
  412.       for(int var2 = 0; var2 < var3; ++var2) {
  413.          RTFAttribute var4 = RTFAttributes.attributes[var2];
  414.          if (var4.domain() == 2) {
  415.             var4.setDefault(var1);
  416.          }
  417.       }
  418.  
  419.       var1.removeAttribute("sectionStyle");
  420.    }
  421.  
  422.    void updateParagraphAttributes(MutableAttributeSet var1, AttributeSet var2, boolean var3) throws IOException {
  423.       Object var4;
  424.       Integer var5;
  425.       if (var3) {
  426.          var4 = var1.getAttribute("paragraphStyle");
  427.          var5 = this.findStyleNumber(var2, "paragraph");
  428.          if (var4 != var5 && var4 != null) {
  429.             this.resetParagraphAttributes(var1);
  430.             var4 = null;
  431.          }
  432.       } else {
  433.          var4 = null;
  434.          var5 = null;
  435.       }
  436.  
  437.       Object var6 = var1.getAttribute("tabs");
  438.       Object var7 = var2.getAttribute("tabs");
  439.       if (var6 != var7 && var6 != null) {
  440.          this.resetParagraphAttributes(var1);
  441.          var6 = null;
  442.          var4 = null;
  443.       }
  444.  
  445.       if (var4 != var5 && var5 != null) {
  446.          this.writeControlWord("s", (Integer)var5);
  447.          var1.addAttribute("paragraphStyle", var5);
  448.       }
  449.  
  450.       this.checkControlWords(var1, var2, RTFAttributes.attributes, 1);
  451.       if (var6 != var7 && var7 != null) {
  452.          TabStop[] var8 = (TabStop[])var7;
  453.  
  454.          for(int var9 = 0; var9 < var8.length; ++var9) {
  455.             TabStop var10 = var8[var9];
  456.             switch (var10.getAlignment()) {
  457.                case 0:
  458.                case 3:
  459.                case 5:
  460.                default:
  461.                   break;
  462.                case 1:
  463.                   this.writeControlWord("tqr");
  464.                   break;
  465.                case 2:
  466.                   this.writeControlWord("tqc");
  467.                   break;
  468.                case 4:
  469.                   this.writeControlWord("tqdec");
  470.             }
  471.  
  472.             switch (var10.getLeader()) {
  473.                case 0:
  474.                default:
  475.                   break;
  476.                case 1:
  477.                   this.writeControlWord("tldot");
  478.                   break;
  479.                case 2:
  480.                   this.writeControlWord("tlhyph");
  481.                   break;
  482.                case 3:
  483.                   this.writeControlWord("tlul");
  484.                   break;
  485.                case 4:
  486.                   this.writeControlWord("tlth");
  487.                   break;
  488.                case 5:
  489.                   this.writeControlWord("tleq");
  490.             }
  491.  
  492.             int var11 = Math.round(20.0F * var10.getPosition());
  493.             if (var10.getAlignment() == 5) {
  494.                this.writeControlWord("tb", var11);
  495.             } else {
  496.                this.writeControlWord("tx", var11);
  497.             }
  498.          }
  499.  
  500.          var1.addAttribute("tabs", var8);
  501.       }
  502.  
  503.    }
  504.  
  505.    public void writeParagraphElement(Element var1) throws IOException {
  506.       this.updateParagraphAttributes(this.outputAttributes, var1.getAttributes(), true);
  507.       int var2 = var1.getElementCount();
  508.  
  509.       for(int var3 = 0; var3 < var2; ++var3) {
  510.          this.writeTextElement(var1.getElement(var3));
  511.       }
  512.  
  513.       this.writeControlWord("par");
  514.       this.writeLineBreak();
  515.    }
  516.  
  517.    protected void resetParagraphAttributes(MutableAttributeSet var1) throws IOException {
  518.       this.writeControlWord("pard");
  519.       var1.addAttribute(StyleConstants.Alignment, Zero);
  520.       int var3 = RTFAttributes.attributes.length;
  521.  
  522.       for(int var2 = 0; var2 < var3; ++var2) {
  523.          RTFAttribute var4 = RTFAttributes.attributes[var2];
  524.          if (var4.domain() == 1) {
  525.             var4.setDefault(var1);
  526.          }
  527.       }
  528.  
  529.       var1.removeAttribute("paragraphStyle");
  530.       var1.removeAttribute("tabs");
  531.    }
  532.  
  533.    void updateCharacterAttributes(MutableAttributeSet var1, AttributeSet var2, boolean var3) throws IOException {
  534.       if (var3) {
  535.          Object var5 = var1.getAttribute("characterStyle");
  536.          Integer var6 = this.findStyleNumber(var2, "character");
  537.          if (var5 != var6) {
  538.             if (var5 != null) {
  539.                this.resetCharacterAttributes(var1);
  540.             }
  541.  
  542.             if (var6 != null) {
  543.                this.writeControlWord("cs", (Integer)var6);
  544.                var1.addAttribute("characterStyle", var6);
  545.             } else {
  546.                var1.removeAttribute("characterStyle");
  547.             }
  548.          }
  549.       }
  550.  
  551.       Object var4;
  552.       if ((var4 = attrDiff(var1, var2, StyleConstants.FontFamily, (Object)null)) != null) {
  553.          Number var9 = (Number)this.fontTable.get(var4);
  554.          this.writeControlWord("f", var9.intValue());
  555.       }
  556.  
  557.       this.checkNumericControlWord(var1, var2, StyleConstants.FontSize, "fs", 12.0F, 2.0F);
  558.       this.checkControlWords(var1, var2, RTFAttributes.attributes, 0);
  559.       this.checkNumericControlWord(var1, var2, StyleConstants.LineSpacing, "sl", 0.0F, 20.0F);
  560.       if ((var4 = attrDiff(var1, var2, StyleConstants.Background, MagicToken)) != null) {
  561.          int var10;
  562.          if (var4 == MagicToken) {
  563.             var10 = 0;
  564.          } else {
  565.             var10 = ((Number)this.colorTable.get(var4)).intValue();
  566.          }
  567.  
  568.          this.writeControlWord("cb", var10);
  569.       }
  570.  
  571.       if ((var4 = attrDiff(var1, var2, StyleConstants.Foreground, (Object)null)) != null) {
  572.          int var11;
  573.          if (var4 == MagicToken) {
  574.             var11 = 0;
  575.          } else {
  576.             var11 = ((Number)this.colorTable.get(var4)).intValue();
  577.          }
  578.  
  579.          this.writeControlWord("cf", var11);
  580.       }
  581.  
  582.    }
  583.  
  584.    protected void resetCharacterAttributes(MutableAttributeSet var1) throws IOException {
  585.       this.writeControlWord("plain");
  586.       int var3 = RTFAttributes.attributes.length;
  587.  
  588.       for(int var2 = 0; var2 < var3; ++var2) {
  589.          RTFAttribute var4 = RTFAttributes.attributes[var2];
  590.          if (var4.domain() == 0) {
  591.             var4.setDefault(var1);
  592.          }
  593.       }
  594.  
  595.       StyleConstants.setFontFamily(var1, "Helvetica");
  596.       var1.removeAttribute(StyleConstants.FontSize);
  597.       var1.removeAttribute(StyleConstants.Background);
  598.       var1.removeAttribute(StyleConstants.Foreground);
  599.       var1.removeAttribute(StyleConstants.LineSpacing);
  600.       var1.removeAttribute("characterStyle");
  601.    }
  602.  
  603.    public void writeTextElement(Element var1) throws IOException {
  604.       this.updateCharacterAttributes(this.outputAttributes, var1.getAttributes(), true);
  605.       if (var1.isLeaf()) {
  606.          try {
  607.             var1.getDocument().getText(var1.getStartOffset(), var1.getEndOffset(), this.workingSegment);
  608.          } catch (BadLocationException var4) {
  609.             throw new InternalError(((Throwable)var4).getMessage());
  610.          }
  611.  
  612.          this.writeText(this.workingSegment);
  613.       } else {
  614.          int var2 = var1.getElementCount();
  615.  
  616.          for(int var3 = 0; var3 < var2; ++var3) {
  617.             this.writeTextElement(var1.getElement(var3));
  618.          }
  619.  
  620.       }
  621.    }
  622.  
  623.    public void writeText(Segment var1) throws IOException {
  624.       int var2 = var1.offset;
  625.       int var3 = var1.count;
  626.  
  627.       for(char[] var4 = var1.array; var2 < var3; ++var2) {
  628.          this.writeCharacter(var4[var2]);
  629.       }
  630.  
  631.    }
  632.  
  633.    public void writeText(String var1) throws IOException {
  634.       int var2 = 0;
  635.  
  636.       for(int var3 = var1.length(); var2 < var3; ++var2) {
  637.          this.writeCharacter(var1.charAt(var2));
  638.       }
  639.  
  640.    }
  641.  
  642.    public void writeRawString(String var1) throws IOException {
  643.       int var2 = var1.length();
  644.  
  645.       for(int var3 = 0; var3 < var2; ++var3) {
  646.          this.outputStream.write(var1.charAt(var3));
  647.       }
  648.  
  649.    }
  650.  
  651.    public void writeControlWord(String var1) throws IOException {
  652.       this.outputStream.write(92);
  653.       this.writeRawString(var1);
  654.       this.afterKeyword = true;
  655.    }
  656.  
  657.    public void writeControlWord(String var1, int var2) throws IOException {
  658.       this.outputStream.write(92);
  659.       this.writeRawString(var1);
  660.       this.writeRawString(String.valueOf(var2));
  661.       this.afterKeyword = true;
  662.    }
  663.  
  664.    public void writeBegingroup() throws IOException {
  665.       this.outputStream.write(123);
  666.       this.afterKeyword = false;
  667.    }
  668.  
  669.    public void writeEndgroup() throws IOException {
  670.       this.outputStream.write(125);
  671.       this.afterKeyword = false;
  672.    }
  673.  
  674.    public void writeCharacter(char var1) throws IOException {
  675.       if (var1 == 160) {
  676.          this.outputStream.write(92);
  677.          this.outputStream.write(126);
  678.          this.afterKeyword = false;
  679.       } else if (var1 == '\t') {
  680.          this.writeControlWord("tab");
  681.       } else if (var1 != '\n' && var1 != '\r') {
  682.          int var2 = convertCharacter(this.outputConversion, var1);
  683.          if (var2 != 0) {
  684.             if (var2 > 127) {
  685.                this.outputStream.write(92);
  686.                this.outputStream.write(39);
  687.                int var5 = (var2 & 240) >>> 4;
  688.                this.outputStream.write(hexdigits[var5]);
  689.                var5 = var2 & 15;
  690.                this.outputStream.write(hexdigits[var5]);
  691.                this.afterKeyword = false;
  692.             } else {
  693.                switch (var2) {
  694.                   case 92:
  695.                   case 123:
  696.                   case 125:
  697.                      this.outputStream.write(92);
  698.                      this.afterKeyword = false;
  699.                   default:
  700.                      if (this.afterKeyword) {
  701.                         this.outputStream.write(32);
  702.                         this.afterKeyword = false;
  703.                      }
  704.  
  705.                      this.outputStream.write(var2);
  706.                }
  707.             }
  708.          } else {
  709.             for(int var3 = 0; var3 < textKeywords.length; ++var3) {
  710.                if (textKeywords[var3].character == var1) {
  711.                   this.writeControlWord(textKeywords[var3].keyword);
  712.                   return;
  713.                }
  714.             }
  715.  
  716.             String var4 = this.approximationForUnicode(var1);
  717.             if (var4.length() != this.unicodeCount) {
  718.                this.unicodeCount = var4.length();
  719.                this.writeControlWord("uc", this.unicodeCount);
  720.             }
  721.  
  722.             this.writeControlWord("u", var1);
  723.             this.writeRawString(" ");
  724.             this.writeRawString(var4);
  725.             this.afterKeyword = false;
  726.          }
  727.       }
  728.    }
  729.  
  730.    String approximationForUnicode(char var1) {
  731.       return "?";
  732.    }
  733.  
  734.    static int[] outputConversionFromTranslationTable(char[] var0) {
  735.       int[] var1 = new int[2 * var0.length];
  736.  
  737.       for(int var2 = 0; var2 < var0.length; var1[var2 * 2 + 1] = var2++) {
  738.          var1[var2 * 2] = var0[var2];
  739.       }
  740.  
  741.       return var1;
  742.    }
  743.  
  744.    static int[] outputConversionForName(String var0) throws IOException {
  745.       char[] var1 = (char[])RTFReader.getCharacterSet(var0);
  746.       return outputConversionFromTranslationTable(var1);
  747.    }
  748.  
  749.    protected static int convertCharacter(int[] var0, char var1) {
  750.       for(int var2 = 0; var2 < var0.length; var2 += 2) {
  751.          if (var0[var2] == var1) {
  752.             return var0[var2 + 1];
  753.          }
  754.       }
  755.  
  756.       return 0;
  757.    }
  758.  
  759.    static {
  760.       defaultRTFColor = Color.black;
  761.       One = new Integer(1);
  762.       Zero = new Integer(0);
  763.       False = new Boolean(false);
  764.       MagicToken = new Object();
  765.       ZeroPointZero = new Float(0.0F);
  766.       Dictionary var0 = RTFReader.textKeywords;
  767.       Enumeration var1 = var0.keys();
  768.       Vector var2 = new Vector();
  769.  
  770.       while(var1.hasMoreElements()) {
  771.          CharacterKeywordPair var3 = new CharacterKeywordPair();
  772.          var3.keyword = (String)var1.nextElement();
  773.          var3.character = ((String)var0.get(var3.keyword)).charAt(0);
  774.          var2.addElement(var3);
  775.       }
  776.  
  777.       textKeywords = new CharacterKeywordPair[var2.size()];
  778.       var2.copyInto(textKeywords);
  779.       hexdigits = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
  780.    }
  781. }
  782.