📄 rtfreader.java
字号:
public void endgroup(Dictionary oldState) { characterAttributes = (MutableAttributeSet)parserState.get("chr"); paragraphAttributes = (MutableAttributeSet)parserState.get("pgf"); sectionAttributes = (MutableAttributeSet)parserState.get("sec"); } public void close() { } public boolean handleKeyword(String keyword) { if (keyword.equals("ulnone")) { return handleKeyword("ul", 0); } { Object item = straightforwardAttributes.get(keyword); if (item != null) { RTFAttribute attr = (RTFAttribute)item; boolean ok; switch(attr.domain()) { case RTFAttribute.D_CHARACTER: ok = attr.set(characterAttributes); break; case RTFAttribute.D_PARAGRAPH: ok = attr.set(paragraphAttributes); break; case RTFAttribute.D_SECTION: ok = attr.set(sectionAttributes); break; case RTFAttribute.D_META: mockery.backing = parserState; ok = attr.set(mockery); mockery.backing = null; break; case RTFAttribute.D_DOCUMENT: ok = attr.set(documentAttributes); break; default: /* should never happen */ ok = false; break; } if (ok) return true; } } if (keyword.equals("plain")) { resetCharacterAttributes(); return true; } if (keyword.equals("pard")) { resetParagraphAttributes(); return true; } if (keyword.equals("sectd")) { resetSectionAttributes(); return true; } return false; } public boolean handleKeyword(String keyword, int parameter) { boolean booleanParameter = (parameter != 0); if (keyword.equals("fc")) keyword = "cf"; /* whatEVER, dude. */ if (keyword.equals("f")) { parserState.put(keyword, Integer.valueOf(parameter)); return true; } if (keyword.equals("cf")) { parserState.put(keyword, Integer.valueOf(parameter)); return true; } { Object item = straightforwardAttributes.get(keyword); if (item != null) { RTFAttribute attr = (RTFAttribute)item; boolean ok; switch(attr.domain()) { case RTFAttribute.D_CHARACTER: ok = attr.set(characterAttributes, parameter); break; case RTFAttribute.D_PARAGRAPH: ok = attr.set(paragraphAttributes, parameter); break; case RTFAttribute.D_SECTION: ok = attr.set(sectionAttributes, parameter); break; case RTFAttribute.D_META: mockery.backing = parserState; ok = attr.set(mockery, parameter); mockery.backing = null; break; case RTFAttribute.D_DOCUMENT: ok = attr.set(documentAttributes, parameter); break; default: /* should never happen */ ok = false; break; } if (ok) return true; } } if (keyword.equals("fs")) { StyleConstants.setFontSize(characterAttributes, (parameter / 2)); return true; } /* TODO: superscript/subscript */ if (keyword.equals("sl")) { if (parameter == 1000) { /* magic value! */ characterAttributes.removeAttribute(StyleConstants.LineSpacing); } else { /* TODO: The RTF sl attribute has special meaning if it's negative. Make sure that SwingText has the same special meaning, or find a way to imitate that. When SwingText handles this, also recognize the slmult keyword. */ StyleConstants.setLineSpacing(characterAttributes, parameter / 20f); } return true; } /* TODO: Other kinds of underlining */ if (keyword.equals("tx") || keyword.equals("tb")) { float tabPosition = parameter / 20f; int tabAlignment, tabLeader; Number item; tabAlignment = TabStop.ALIGN_LEFT; item = (Number)(parserState.get("tab_alignment")); if (item != null) tabAlignment = item.intValue(); tabLeader = TabStop.LEAD_NONE; item = (Number)(parserState.get("tab_leader")); if (item != null) tabLeader = item.intValue(); if (keyword.equals("tb")) tabAlignment = TabStop.ALIGN_BAR; parserState.remove("tab_alignment"); parserState.remove("tab_leader"); TabStop newStop = new TabStop(tabPosition, tabAlignment, tabLeader); Dictionary tabs; Integer stopCount; tabs = (Dictionary)parserState.get("_tabs"); if (tabs == null) { tabs = new Hashtable(); parserState.put("_tabs", tabs); stopCount = Integer.valueOf(1); } else { stopCount = (Integer)tabs.get("stop count"); stopCount = Integer.valueOf(1 + stopCount.intValue()); } tabs.put(stopCount, newStop); tabs.put("stop count", stopCount); parserState.remove("_tabs_immutable"); return true; } if (keyword.equals("s") && paragraphStyles != null) { parserState.put("paragraphStyle", paragraphStyles[parameter]); return true; } if (keyword.equals("cs") && characterStyles != null) { parserState.put("characterStyle", characterStyles[parameter]); return true; } if (keyword.equals("ds") && sectionStyles != null) { parserState.put("sectionStyle", sectionStyles[parameter]); return true; } return false; } /** Returns a new MutableAttributeSet containing the * default character attributes */ protected MutableAttributeSet rootCharacterAttributes() { MutableAttributeSet set = new SimpleAttributeSet(); /* TODO: default font */ StyleConstants.setItalic(set, false); StyleConstants.setBold(set, false); StyleConstants.setUnderline(set, false); StyleConstants.setForeground(set, defaultColor()); return set; } /** Returns a new MutableAttributeSet containing the * default paragraph attributes */ protected MutableAttributeSet rootParagraphAttributes() { MutableAttributeSet set = new SimpleAttributeSet(); StyleConstants.setLeftIndent(set, 0f); StyleConstants.setRightIndent(set, 0f); StyleConstants.setFirstLineIndent(set, 0f); /* TODO: what should this be, really? */ set.setResolveParent(target.getStyle(StyleContext.DEFAULT_STYLE)); return set; } /** Returns a new MutableAttributeSet containing the * default section attributes */ protected MutableAttributeSet rootSectionAttributes() { MutableAttributeSet set = new SimpleAttributeSet(); return set; } /** * Calculates the current text (character) attributes in a form suitable * for SwingText from the current parser state. * * @returns a new MutableAttributeSet containing the text attributes. */ MutableAttributeSet currentTextAttributes() { MutableAttributeSet attributes = new SimpleAttributeSet(characterAttributes); Integer fontnum; Integer stateItem; /* figure out the font name */ /* TODO: catch exceptions for undefined attributes, bad font indices, etc.? (as it stands, it is the caller's job to clean up after corrupt RTF) */ fontnum = (Integer)parserState.get("f"); /* note setFontFamily() can not handle a null font */ String fontFamily; if (fontnum != null) fontFamily = (String)fontTable.get(fontnum); else fontFamily = null; if (fontFamily != null) StyleConstants.setFontFamily(attributes, fontFamily); else attributes.removeAttribute(StyleConstants.FontFamily); if (colorTable != null) { stateItem = (Integer)parserState.get("cf"); if (stateItem != null) { Color fg = colorTable[stateItem.intValue()]; StyleConstants.setForeground(attributes, fg); } else { /* AttributeSet dies if you set a value to null */ attributes.removeAttribute(StyleConstants.Foreground); } } if (colorTable != null) { stateItem = (Integer)parserState.get("cb"); if (stateItem != null) { Color bg = colorTable[stateItem.intValue()]; attributes.addAttribute(StyleConstants.Background, bg); } else { /* AttributeSet dies if you set a value to null */ attributes.removeAttribute(StyleConstants.Background); } } Style characterStyle = (Style)parserState.get("characterStyle"); if (characterStyle != null) attributes.setResolveParent(characterStyle); /* Other attributes are maintained directly in "attributes" */ return attributes; } /** * Calculates the current paragraph attributes (with keys * as given in StyleConstants) from the current parser state. * * @returns a newly created MutableAttributeSet. * @see StyleConstants */ MutableAttributeSet currentParagraphAttributes() { /* NB if there were a mutableCopy() method we should use it */ MutableAttributeSet bld = new SimpleAttributeSet(paragraphAttributes); Integer stateItem; /*** Tab stops ***/ TabStop tabs[]; tabs = (TabStop[])parserState.get("_tabs_immutable"); if (tabs == null) { Dictionary workingTabs = (Dictionary)parserState.get("_tabs"); if (workingTabs != null) { int count = ((Integer)workingTabs.get("stop count")).intValue(); tabs = new TabStop[count]; for (int ix = 1; ix <= count; ix ++) tabs[ix-1] = (TabStop)workingTabs.get(Integer.valueOf(ix)); parserState.put("_tabs_immutable", tabs); } } if (tabs != null) bld.addAttribute(Constants.Tabs, tabs); Style paragraphStyle = (Style)parserState.get("paragraphStyle"); if (paragraphStyle != null) bld.setResolveParent(paragraphStyle); return bld; } /** * Calculates the current section attributes * from the current parser state. * * @returns a newly created MutableAttributeSet. */ public AttributeSet currentSectionAttributes() { MutableAttributeSet attributes = new SimpleAttributeSet(sectionAttributes); Style sectionStyle = (Style)parserState.get("sectionStyle"); if (sectionStyle != null) attributes.setResolveParent(sectionStyle); return attributes; } /** Resets the filter's internal notion of the current character * attributes to their default values. Invoked to handle the * \plain keyword. */ protected void resetCharacterAttributes() { handleKeyword("f", 0); handleKeyword("cf", 0); handleKeyword("fs", 24); /* 12 pt. */ Enumeration attributes = straightforwardAttributes.elements(); while(attributes.hasMoreElements()) { RTFAttribute attr = (RTFAttribute)attributes.nextElement(); if (attr.domain() == RTFAttribute.D_CHARACTER) attr.setDefault(characterAttributes); } handleKeyword("sl", 1000); parserState.remove("characterStyle"); } /** Resets the filter's internal notion of the current paragraph's * attributes to their default values. Invoked to handle the * \pard keyword. */ protected void resetParagraphAttributes() { parserState.remove("_tabs"); parserState.remove("_tabs_immutable"); parserState.remove("paragraphStyle"); StyleConstants.setAlignment(paragraphAttributes, StyleConstants.ALIGN_LEFT); Enumeration attributes = straightforwardAttributes.elements(); while(attributes.hasMoreElements()) { RTFAttribute attr = (RTFAttribute)attributes.nextElement(); if (attr.domain() == RTFAttribute.D_PARAGRAPH) attr.setDefault(characterAttributes); } } /** Resets the filter's internal notion of the current section's * attributes to their default values. Invoked to handle the * \sectd keyword. */ protected void resetSectionAttributes() { Enumeration attributes = straightforwardAttributes.elements(); while(attributes.hasMoreElements()) { RTFAttribute attr = (RTFAttribute)attributes.nextElement(); if (attr.domain() == RTFAttribute.D_SECTION) attr.setDefault(characterAttributes); } parserState.remove("sectionStyle"); }}/** RTFReader.TextHandlingDestination provides basic text handling * functionality. Subclasses must implement: <dl> * <dt>deliverText()<dd>to handle a run of text with the same * attributes * <dt>finishParagraph()<dd>to end the current paragraph and * set the paragraph's attributes * <dt>endSection()<dd>to end the current section * </dl> */abstract class TextHandlingDestination extends AttributeTrackingDestination implements Destination{ /** <code>true</code> if the reader has not just finished * a paragraph; false upon startup */ boolean inParagraph; public TextHandlingDestination() { super(); inParagraph = false; } public void handleText(String text) { if (! inParagraph) beginParagraph(); deliverText(text, currentTextAttributes()); } abstract void deliverText(String text, AttributeSet characterAttributes); public void close() { if (inParagraph) endParagraph(); super.close(); } public boolean handleKeyword(String keyword) { if (keyword.equals("\r") || keyword.equals("\n")) { keyword = "par"; } if (keyword.equals("par")) {// warnings.println("Ending paragraph."); endParagraph(); return true; } if (keyword.equals("sect")) {// warnings.println("Ending section."); endSection(); return true; } return super.handleKeyword(keyword); } protected void beginParagraph() { inParagraph = true; } protected void endParagraph() { AttributeSet pgfAttributes = currentParagraphAttributes(); AttributeSet chrAttributes = currentTextAttributes(); finishParagraph(pgfAttributes, chrAttributes); inParagraph = false; } abstract void finishParagraph(AttributeSet pgfA, AttributeSet chrA); abstract void endSection();}/** RTFReader.DocumentDestination is a concrete subclass of * TextHandlingDestination which appends the text to the * StyledDocument given by the <code>target</code> ivar of the * containing RTFReader. */class DocumentDestination extends TextHandlingDestination implements Destination{ public void deliverText(String text, AttributeSet characterAttributes) { try { target.insertString(target.getLength(), text, currentTextAttributes()); } catch (BadLocationException ble) { /* This shouldn't be able to happen, of course */ /* TODO is InternalError the correct error to throw? */ throw new InternalError(ble.getMessage()); } } public void finishParagraph(AttributeSet pgfAttributes, AttributeSet chrAttributes) { int pgfEndPosition = target.getLength(); try { target.insertString(pgfEndPosition, "\n", chrAttributes); target.setParagraphAttributes(pgfEndPosition, 1, pgfAttributes, true); } catch (BadLocationException ble) { /* This shouldn't be able to happen, of course */ /* TODO is InternalError the correct error to throw? */ throw new InternalError(ble.getMessage()); } } public void endSection() { /* If we implemented sections, we'd end 'em here */ }}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -