📄 reader.c
字号:
RTFFont *RTFGetFont(RTF_Info *info, int num)
{
RTFFont *f;
if (num == -1)
return (info->fontList);
for (f = info->fontList; f != NULL; f = f->rtfNextFont)
{
if (f->rtfFNum == num)
break;
}
return (f); /* NULL if not found */
}
RTFColor *RTFGetColor(RTF_Info *info, int num)
{
RTFColor *c;
if (num == -1)
return (info->colorList);
for (c = info->colorList; c != NULL; c = c->rtfNextColor)
{
if (c->rtfCNum == num)
break;
}
return (c); /* NULL if not found */
}
/* ---------------------------------------------------------------------- */
/*
* Expand style n, if there is such a style.
*/
void RTFExpandStyle(RTF_Info *info, int n)
{
RTFStyle *s;
RTFStyleElt *se;
if (n == -1)
return;
s = RTFGetStyle (info, n);
if (s == NULL)
return;
if (s->rtfExpanding != 0)
ERR ("Style expansion loop, style %d\n", n);
s->rtfExpanding = 1; /* set expansion flag for loop detection */
/*
* Expand "based-on" style (unless it's the same as the current
* style -- Normal style usually gives itself as its own based-on
* style). Based-on style expansion is done by synthesizing
* the token that the writer needs to see in order to trigger
* another style expansion, and feeding to token back through
* the router so the writer sees it.
*/
if (n != s->rtfSBasedOn)
{
RTFSetToken (info, rtfControl, rtfParAttr, rtfStyleNum,
s->rtfSBasedOn, "\\s");
RTFRouteToken (info);
}
/*
* Now route the tokens unique to this style. RTFSetToken()
* isn't used because it would add the param value to the end
* of the token text, which already has it in.
*/
for (se = s->rtfSSEList; se != NULL; se = se->rtfNextSE)
{
info->rtfClass = se->rtfSEClass;
info->rtfMajor = se->rtfSEMajor;
info->rtfMinor = se->rtfSEMinor;
info->rtfParam = se->rtfSEParam;
lstrcpyA (info->rtfTextBuf, se->rtfSEText);
info->rtfTextLen = lstrlenA (info->rtfTextBuf);
RTFRouteToken (info);
}
s->rtfExpanding = 0; /* done - clear expansion flag */
}
/* ---------------------------------------------------------------------- */
/*
* Control symbol lookup routines
*/
typedef struct RTFKey RTFKey;
struct RTFKey
{
int rtfKMajor; /* major number */
int rtfKMinor; /* minor number */
const char *rtfKStr; /* symbol name */
int rtfKHash; /* symbol name hash value */
};
/*
* A minor number of -1 means the token has no minor number
* (all valid minor numbers are >= 0).
*/
static RTFKey rtfKey[] =
{
/*
* Special characters
*/
{ rtfSpecialChar, rtfIIntVersion, "vern", 0 },
{ rtfSpecialChar, rtfICreateTime, "creatim", 0 },
{ rtfSpecialChar, rtfIRevisionTime, "revtim", 0 },
{ rtfSpecialChar, rtfIPrintTime, "printim", 0 },
{ rtfSpecialChar, rtfIBackupTime, "buptim", 0 },
{ rtfSpecialChar, rtfIEditTime, "edmins", 0 },
{ rtfSpecialChar, rtfIYear, "yr", 0 },
{ rtfSpecialChar, rtfIMonth, "mo", 0 },
{ rtfSpecialChar, rtfIDay, "dy", 0 },
{ rtfSpecialChar, rtfIHour, "hr", 0 },
{ rtfSpecialChar, rtfIMinute, "min", 0 },
{ rtfSpecialChar, rtfISecond, "sec", 0 },
{ rtfSpecialChar, rtfINPages, "nofpages", 0 },
{ rtfSpecialChar, rtfINWords, "nofwords", 0 },
{ rtfSpecialChar, rtfINChars, "nofchars", 0 },
{ rtfSpecialChar, rtfIIntID, "id", 0 },
{ rtfSpecialChar, rtfCurHeadDate, "chdate", 0 },
{ rtfSpecialChar, rtfCurHeadDateLong, "chdpl", 0 },
{ rtfSpecialChar, rtfCurHeadDateAbbrev, "chdpa", 0 },
{ rtfSpecialChar, rtfCurHeadTime, "chtime", 0 },
{ rtfSpecialChar, rtfCurHeadPage, "chpgn", 0 },
{ rtfSpecialChar, rtfSectNum, "sectnum", 0 },
{ rtfSpecialChar, rtfCurFNote, "chftn", 0 },
{ rtfSpecialChar, rtfCurAnnotRef, "chatn", 0 },
{ rtfSpecialChar, rtfFNoteSep, "chftnsep", 0 },
{ rtfSpecialChar, rtfFNoteCont, "chftnsepc", 0 },
{ rtfSpecialChar, rtfCell, "cell", 0 },
{ rtfSpecialChar, rtfRow, "row", 0 },
{ rtfSpecialChar, rtfPar, "par", 0 },
/* newline and carriage return are synonyms for */
/* \par when they are preceded by a \ character */
{ rtfSpecialChar, rtfPar, "\n", 0 },
{ rtfSpecialChar, rtfPar, "\r", 0 },
{ rtfSpecialChar, rtfSect, "sect", 0 },
{ rtfSpecialChar, rtfPage, "page", 0 },
{ rtfSpecialChar, rtfColumn, "column", 0 },
{ rtfSpecialChar, rtfLine, "line", 0 },
{ rtfSpecialChar, rtfSoftPage, "softpage", 0 },
{ rtfSpecialChar, rtfSoftColumn, "softcol", 0 },
{ rtfSpecialChar, rtfSoftLine, "softline", 0 },
{ rtfSpecialChar, rtfSoftLineHt, "softlheight", 0 },
{ rtfSpecialChar, rtfTab, "tab", 0 },
{ rtfSpecialChar, rtfEmDash, "emdash", 0 },
{ rtfSpecialChar, rtfEnDash, "endash", 0 },
{ rtfSpecialChar, rtfEmSpace, "emspace", 0 },
{ rtfSpecialChar, rtfEnSpace, "enspace", 0 },
{ rtfSpecialChar, rtfBullet, "bullet", 0 },
{ rtfSpecialChar, rtfLQuote, "lquote", 0 },
{ rtfSpecialChar, rtfRQuote, "rquote", 0 },
{ rtfSpecialChar, rtfLDblQuote, "ldblquote", 0 },
{ rtfSpecialChar, rtfRDblQuote, "rdblquote", 0 },
{ rtfSpecialChar, rtfFormula, "|", 0 },
{ rtfSpecialChar, rtfNoBrkSpace, "~", 0 },
{ rtfSpecialChar, rtfNoReqHyphen, "-", 0 },
{ rtfSpecialChar, rtfNoBrkHyphen, "_", 0 },
{ rtfSpecialChar, rtfOptDest, "*", 0 },
{ rtfSpecialChar, rtfLTRMark, "ltrmark", 0 },
{ rtfSpecialChar, rtfRTLMark, "rtlmark", 0 },
{ rtfSpecialChar, rtfNoWidthJoiner, "zwj", 0 },
{ rtfSpecialChar, rtfNoWidthNonJoiner, "zwnj", 0 },
/* is this valid? */
{ rtfSpecialChar, rtfCurHeadPict, "chpict", 0 },
{ rtfSpecialChar, rtfUnicode, "u", 0 },
/*
* Character formatting attributes
*/
{ rtfCharAttr, rtfPlain, "plain", 0 },
{ rtfCharAttr, rtfBold, "b", 0 },
{ rtfCharAttr, rtfAllCaps, "caps", 0 },
{ rtfCharAttr, rtfDeleted, "deleted", 0 },
{ rtfCharAttr, rtfSubScript, "dn", 0 },
{ rtfCharAttr, rtfSubScrShrink, "sub", 0 },
{ rtfCharAttr, rtfNoSuperSub, "nosupersub", 0 },
{ rtfCharAttr, rtfExpand, "expnd", 0 },
{ rtfCharAttr, rtfExpandTwips, "expndtw", 0 },
{ rtfCharAttr, rtfKerning, "kerning", 0 },
{ rtfCharAttr, rtfFontNum, "f", 0 },
{ rtfCharAttr, rtfFontSize, "fs", 0 },
{ rtfCharAttr, rtfItalic, "i", 0 },
{ rtfCharAttr, rtfOutline, "outl", 0 },
{ rtfCharAttr, rtfRevised, "revised", 0 },
{ rtfCharAttr, rtfRevAuthor, "revauth", 0 },
{ rtfCharAttr, rtfRevDTTM, "revdttm", 0 },
{ rtfCharAttr, rtfSmallCaps, "scaps", 0 },
{ rtfCharAttr, rtfShadow, "shad", 0 },
{ rtfCharAttr, rtfStrikeThru, "strike", 0 },
{ rtfCharAttr, rtfUnderline, "ul", 0 },
{ rtfCharAttr, rtfDotUnderline, "uld", 0 },
{ rtfCharAttr, rtfDbUnderline, "uldb", 0 },
{ rtfCharAttr, rtfNoUnderline, "ulnone", 0 },
{ rtfCharAttr, rtfWordUnderline, "ulw", 0 },
{ rtfCharAttr, rtfSuperScript, "up", 0 },
{ rtfCharAttr, rtfSuperScrShrink, "super", 0 },
{ rtfCharAttr, rtfInvisible, "v", 0 },
{ rtfCharAttr, rtfForeColor, "cf", 0 },
{ rtfCharAttr, rtfBackColor, "cb", 0 },
{ rtfCharAttr, rtfRTLChar, "rtlch", 0 },
{ rtfCharAttr, rtfLTRChar, "ltrch", 0 },
{ rtfCharAttr, rtfCharStyleNum, "cs", 0 },
{ rtfCharAttr, rtfCharCharSet, "cchs", 0 },
{ rtfCharAttr, rtfLanguage, "lang", 0 },
/* this has disappeared from spec 1.2 */
{ rtfCharAttr, rtfGray, "gray", 0 },
{ rtfCharAttr, rtfUnicodeLength, "uc", 0 },
/*
* Paragraph formatting attributes
*/
{ rtfParAttr, rtfParDef, "pard", 0 },
{ rtfParAttr, rtfStyleNum, "s", 0 },
{ rtfParAttr, rtfHyphenate, "hyphpar", 0 },
{ rtfParAttr, rtfInTable, "intbl", 0 },
{ rtfParAttr, rtfKeep, "keep", 0 },
{ rtfParAttr, rtfNoWidowControl, "nowidctlpar", 0 },
{ rtfParAttr, rtfKeepNext, "keepn", 0 },
{ rtfParAttr, rtfOutlineLevel, "level", 0 },
{ rtfParAttr, rtfNoLineNum, "noline", 0 },
{ rtfParAttr, rtfPBBefore, "pagebb", 0 },
{ rtfParAttr, rtfSideBySide, "sbys", 0 },
{ rtfParAttr, rtfQuadLeft, "ql", 0 },
{ rtfParAttr, rtfQuadRight, "qr", 0 },
{ rtfParAttr, rtfQuadJust, "qj", 0 },
{ rtfParAttr, rtfQuadCenter, "qc", 0 },
{ rtfParAttr, rtfFirstIndent, "fi", 0 },
{ rtfParAttr, rtfLeftIndent, "li", 0 },
{ rtfParAttr, rtfRightIndent, "ri", 0 },
{ rtfParAttr, rtfSpaceBefore, "sb", 0 },
{ rtfParAttr, rtfSpaceAfter, "sa", 0 },
{ rtfParAttr, rtfSpaceBetween, "sl", 0 },
{ rtfParAttr, rtfSpaceMultiply, "slmult", 0 },
{ rtfParAttr, rtfSubDocument, "subdocument", 0 },
{ rtfParAttr, rtfRTLPar, "rtlpar", 0 },
{ rtfParAttr, rtfLTRPar, "ltrpar", 0 },
{ rtfParAttr, rtfTabPos, "tx", 0 },
/*
* FrameMaker writes \tql (to mean left-justified tab, apparently)
* although it's not in the spec. It's also redundant, since lj
* tabs are the default.
*/
{ rtfParAttr, rtfTabLeft, "tql", 0 },
{ rtfParAttr, rtfTabRight, "tqr", 0 },
{ rtfParAttr, rtfTabCenter, "tqc", 0 },
{ rtfParAttr, rtfTabDecimal, "tqdec", 0 },
{ rtfParAttr, rtfTabBar, "tb", 0 },
{ rtfParAttr, rtfLeaderDot, "tldot", 0 },
{ rtfParAttr, rtfLeaderHyphen, "tlhyph", 0 },
{ rtfParAttr, rtfLeaderUnder, "tlul", 0 },
{ rtfParAttr, rtfLeaderThick, "tlth", 0 },
{ rtfParAttr, rtfLeaderEqual, "tleq", 0 },
{ rtfParAttr, rtfParLevel, "pnlvl", 0 },
{ rtfParAttr, rtfParBullet, "pnlvlblt", 0 },
{ rtfParAttr, rtfParSimple, "pnlvlbody", 0 },
{ rtfParAttr, rtfParNumCont, "pnlvlcont", 0 },
{ rtfParAttr, rtfParNumOnce, "pnnumonce", 0 },
{ rtfParAttr, rtfParNumAcross, "pnacross", 0 },
{ rtfParAttr, rtfParHangIndent, "pnhang", 0 },
{ rtfParAttr, rtfParNumRestart, "pnrestart", 0 },
{ rtfParAttr, rtfParNumCardinal, "pncard", 0 },
{ rtfParAttr, rtfParNumDecimal, "pndec", 0 },
{ rtfParAttr, rtfParNumULetter, "pnucltr", 0 },
{ rtfParAttr, rtfParNumURoman, "pnucrm", 0 },
{ rtfParAttr, rtfParNumLLetter, "pnlcltr", 0 },
{ rtfParAttr, rtfParNumLRoman, "pnlcrm", 0 },
{ rtfParAttr, rtfParNumOrdinal, "pnord", 0 },
{ rtfParAttr, rtfParNumOrdinalText, "pnordt", 0 },
{ rtfParAttr, rtfParNumBold, "pnb", 0 },
{ rtfParAttr, rtfParNumItalic, "pni", 0 },
{ rtfParAttr, rtfParNumAllCaps, "pncaps", 0 },
{ rtfParAttr, rtfParNumSmallCaps, "pnscaps", 0 },
{ rtfParAttr, rtfParNumUnder, "pnul", 0 },
{ rtfParAttr, rtfParNumDotUnder, "pnuld", 0 },
{ rtfParAttr, rtfParNumDbUnder, "pnuldb", 0 },
{ rtfParAttr, rtfParNumNoUnder, "pnulnone", 0 },
{ rtfParAttr, rtfParNumWordUnder, "pnulw", 0 },
{ rtfParAttr, rtfParNumStrikethru, "pnstrike", 0 },
{ rtfParAttr, rtfParNumForeColor, "pncf", 0 },
{ rtfParAttr, rtfParNumFont, "pnf", 0 },
{ rtfParAttr, rtfParNumFontSize, "pnfs", 0 },
{ rtfParAttr, rtfParNumIndent, "pnindent", 0 },
{ rtfParAttr, rtfParNumSpacing, "pnsp", 0 },
{ rtfParAttr, rtfParNumInclPrev, "pnprev", 0 },
{ rtfParAttr, rtfParNumCenter, "pnqc", 0 },
{ rtfParAttr, rtfParNumLeft, "pnql", 0 },
{ rtfParAttr, rtfParNumRight, "pnqr", 0 },
{ rtfParAttr, rtfParNumStartAt, "pnstart", 0 },
{ rtfParAttr, rtfBorderTop, "brdrt", 0 },
{ rtfParAttr, rtfBorderBottom, "brdrb", 0 },
{ rtfParAttr, rtfBorderLeft, "brdrl", 0 },
{ rtfParAttr, rtfBorderRight, "brdrr", 0 },
{ rtfParAttr, rtfBorderBetween, "brdrbtw", 0 },
{ rtfParAttr, rtfBorderBar, "brdrbar", 0 },
{ rtfParAttr, rtfBorderBox, "box", 0 },
{ rtfParAttr, rtfBorderSingle, "brdrs", 0 },
{ rtfParAttr, rtfBorderThick, "brdrth", 0 },
{ rtfParAttr, rtfBorderShadow, "brdrsh", 0 },
{ rtfParAttr, rtfBorderDouble, "brdrdb", 0 },
{ rtfParAttr, rtfBorderDot, "brdrdot", 0 },
{ rtfParAttr, rtfBorderDot, "brdrdash", 0 },
{ rtfParAttr, rtfBorderHair, "brdrhair", 0 },
{ rtfParAttr, rtfBorderWidth, "brdrw", 0 },
{ rtfParAttr, rtfBorderColor, "brdrcf", 0 },
{ rtfParAttr, rtfBorderSpace, "brsp", 0 },
{ rtfParAttr, rtfShading, "shading", 0 },
{ rtfParAttr, rtfBgPatH, "bghoriz", 0 },
{ rtfParAttr, rtfBgPatV, "bgvert", 0 },
{ rtfParAttr, rtfFwdDiagBgPat, "bgfdiag", 0 },
{ rtfParAttr, rtfBwdDiagBgPat, "bgbdiag", 0 },
{ rtfParAttr, rtfHatchBgPat, "bgcross", 0 },
{ rtfParAttr, rtfDiagHatchBgPat, "bgdcross", 0 },
{ rtfParAttr, rtfDarkBgPatH, "bgdkhoriz", 0 },
{ rtfParAttr, rtfDarkBgPatV, "bgdkvert", 0 },
{ rtfParAttr, rtfFwdDarkBgPat, "bgdkfdiag", 0 },
{ rtfParAttr, rtfBwdDarkBgPat, "bgdkbdiag", 0 },
{ rtfParAttr, rtfDarkHatchBgPat, "bgdkcross", 0 },
{ rtfParAttr, rtfDarkDiagHatchBgPat, "bgdkdcross", 0 },
{ rtfParAttr, rtfBgPatLineColor, "cfpat", 0 },
{ rtfParAttr, rtfBgPatColor, "cbpat", 0 },
/*
* Section formatting attributes
*/
{ rtfSectAttr, rtfSectDef, "sectd", 0 },
{ rtfSectAttr, rtfENoteHere, "endnhere", 0 },
{ rtfSectAttr, rtfPrtBinFirst, "binfsxn", 0 },
{ rtfSectAttr, rtfPrtBin, "binsxn", 0 },
{ rtfSectAttr, rtfSectStyleNum, "ds", 0 },
{ rtfSectAttr, rtfNoBreak, "sbknone", 0 },
{ rtfSectAttr, rtfColBreak, "sbkcol", 0 },
{ rtfSectAttr, rtfPageBreak, "sbkpage", 0 },
{ rtfSectAttr, rtfEvenBreak, "sbkeven", 0 },
{ rtfSectAttr, rtfOddBreak, "sbkodd", 0 },
{ rtfSectAttr, rtfColumns, "cols", 0 },
{ rtfSectAttr, rtfColumnSpace, "colsx", 0 },
{ rtfSectAttr, rtfColumnNumber, "colno", 0 },
{ rtfSectAttr, rtfColumnSpRight, "colsr", 0 },
{ rtfSectAttr, rtfColumnWidth, "colw", 0 },
{ rtfSectAttr, rtfColumnLine, "linebetcol", 0 },
{ rtfSectAttr, rtfLineModulus, "linemod", 0 },
{ rtfSectAttr, rtfLineDist, "linex", 0 },
{ rtfSectAttr, rtfLineStarts, "linestarts", 0 },
{ rtfSectAttr, rtfLineRestart, "linerestart", 0 },
{ rtfSectAttr, rtfLineRestartPg, "lineppage", 0 },
{ rtfSectAttr, rtfLineCont, "linecont", 0 },
{ rtfSectAttr, rtfSectPageWid, "pgwsxn", 0 },
{ rtfSectAttr, rtfSectPageHt, "pghsxn", 0 },
{ rtfSectAttr, rtfSectMarginLeft, "marglsxn", 0 },
{ rtfSectAttr, rtfSectMarginRight, "margrsxn", 0 },
{ rtfSectAttr, rtfSectMarginTop, "margtsxn", 0 },
{ rtfSectAttr, rtfSectMarginBottom, "margbsxn", 0 },
{ rtfSectAttr, rtfSectMarginGutter, "guttersxn", 0 },
{ rtfSectAttr, rtfSectLandscape, "lndscpsxn", 0 },
{ rtfSectAttr, rtfTitleSpecial, "titlepg", 0 },
{ rtfSectAttr, rtfHeaderY, "headery", 0 },
{ rtfSectAttr, rtfFooterY, "footery", 0 },
{ rtfSectAttr, rtfPageStarts, "pgnstarts", 0 },
{ rtfSectAttr, rtfPageCont, "pgncont", 0 },
{ rtfSectAttr, rtfPageRestart, "pgnrestart", 0 },
{ rtfSectAttr, rtfPageNumRight, "pgnx", 0 },
{ rtfSectAttr, rtfPageNumTop, "pgny", 0 },
{ rtfSectAttr, rtfPageDecimal, "pgndec", 0 },
{ rtfSectAttr, rtfPageURoman, "pgnucrm", 0 },
{ rtfSectAttr, rtfPageLRoman, "pgnlcrm", 0 },
{ rtfSectAttr, rtfPageULetter, "pgnucltr", 0 },
{ rtfSectAttr, rtfPageLLetter, "pgnlcltr", 0 },
{ rtfSectAttr, rtfPageNumHyphSep, "pgnhnsh", 0 },
{ rtfSectAttr, rtfPageNumSpaceSep, "pgnhnsp", 0 },
{ rtfSectAttr, rtfPageNumColonSep, "pgnhnsc", 0 },
{ rtfSectAttr, rtfPageNumEmdashSep, "pgnhnsm", 0 },
{ rtfSectAttr, rtfPageNumEndashSep, "pgnhnsn", 0 },
{ rtfSectAttr, rtfTopVAlign, "vertalt", 0 },
/* misspelled as "vertal" in specification 1.0 */
{ rtfSectAttr, rtfBottomVAlign, "vertalb", 0 },
{ rtfSectAttr, rtfCenterVAlign, "vertalc", 0 },
{ rtfSectAttr, rtfJustVAlign, "vertalj", 0 },
{ rtfSectAttr, rtfRTLSect, "rtlsect", 0 },
{ rtfSectAttr, rtfLTRSect, "ltrsect", 0 },
/* I've seen these in an old spec, but not in real files... */
/*rtfSectAttr, rtfNoBreak, "nobreak", 0,*/
/*rtfSectAttr, rtfColBreak, "colbreak", 0,*/
/*rtfSectAttr, rtfPageBreak, "pagebreak", 0,*/
/*rtfSectAttr, rtfEvenBreak, "evenbreak", 0,*/
/*rtfSectAttr, rtfOddBreak, "oddbreak", 0,*/
/*
* Document formatting attributes
*/
{ rtfDocAttr, rtfDefTab, "deftab", 0 },
{ rtfDocAttr, rtfHyphHotZone, "hyphhotz", 0 },
{ rtfDocAttr, rtfHyphConsecLines, "hyphconsec", 0 },
{ rtfDocAttr, rtfHyphCaps, "hyphcaps", 0 },
{ rtfDocAttr, rtfHyphAuto, "hyphauto", 0 },
{ rtfDocAttr, rtfLineStart, "linestart", 0 },
{ rtfDocAttr, rtfFracWidth, "fracwidth", 0 },
/* \makeback was given in old version of spec, it's now */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -