📄 reader.c
字号:
else /* can't tell! */
ERR ( "%s: Cannot determine format\n", fn);
}
if (old == 0) /* need to find "{" here */
{
if (!RTFCheckCM (info, rtfGroup, rtfBeginGroup))
ERR ( "%s: missing \"{\"\n", fn);
RTFGetToken (info); /* yes, skip to next token */
if (info->rtfClass == rtfEOF)
break;
}
fp = New (RTFFont);
if (fp == NULL)
ERR ( "%s: cannot allocate font entry\n", fn);
fp->rtfNextFont = info->fontList;
info->fontList = fp;
fp->rtfFName = NULL;
fp->rtfFAltName = NULL;
fp->rtfFNum = -1;
fp->rtfFFamily = 0;
fp->rtfFCharSet = DEFAULT_CHARSET; /* 1 */
fp->rtfFPitch = 0;
fp->rtfFType = 0;
fp->rtfFCodePage = CP_ACP;
while (info->rtfClass != rtfEOF
&& !RTFCheckCM (info, rtfText, ';')
&& !RTFCheckCM (info, rtfGroup, rtfEndGroup))
{
if (info->rtfClass == rtfControl)
{
switch (info->rtfMajor)
{
default:
/* ignore token but announce it */
WARN ("%s: unknown token \"%s\"\n",
fn, info->rtfTextBuf);
break;
case rtfFontFamily:
fp->rtfFFamily = info->rtfMinor;
break;
case rtfCharAttr:
switch (info->rtfMinor)
{
default:
break; /* ignore unknown? */
case rtfFontNum:
fp->rtfFNum = info->rtfParam;
break;
}
break;
case rtfFontAttr:
switch (info->rtfMinor)
{
default:
break; /* ignore unknown? */
case rtfFontCharSet:
fp->rtfFCharSet = info->rtfParam;
if (!fp->rtfFCodePage)
fp->rtfFCodePage = RTFCharSetToCodePage(info, info->rtfParam);
break;
case rtfFontPitch:
fp->rtfFPitch = info->rtfParam;
break;
case rtfFontCodePage:
fp->rtfFCodePage = info->rtfParam;
break;
case rtfFTypeNil:
case rtfFTypeTrueType:
fp->rtfFType = info->rtfParam;
break;
}
break;
}
}
else if (RTFCheckCM (info, rtfGroup, rtfBeginGroup)) /* dest */
{
RTFSkipGroup (info); /* ignore for now */
}
else if (info->rtfClass == rtfText) /* font name */
{
bp = buf;
while (info->rtfClass == rtfText
&& !RTFCheckCM (info, rtfText, ';'))
{
*bp++ = info->rtfMajor;
RTFGetToken (info);
}
/* FIX: in some cases the <fontinfo> isn't finished with a semi-column */
if(RTFCheckCM (info, rtfGroup, rtfEndGroup))
{
RTFUngetToken (info);
}
*bp = '\0';
fp->rtfFName = RTFStrSave (buf);
if (fp->rtfFName == NULL)
ERR ( "%s: cannot allocate font name\n", fn);
/* already have next token; don't read one */
/* at bottom of loop */
continue;
}
else
{
/* ignore token but announce it */
WARN ( "%s: unknown token \"%s\"\n",
fn,info->rtfTextBuf);
}
RTFGetToken (info);
if (info->rtfClass == rtfEOF)
break;
}
if (info->rtfClass == rtfEOF)
break;
if (old == 0) /* need to see "}" here */
{
RTFGetToken (info);
if (!RTFCheckCM (info, rtfGroup, rtfEndGroup))
ERR ( "%s: missing \"}\"\n", fn);
if (info->rtfClass == rtfEOF)
break;
}
/* Apply the real properties of the default font */
if (fp->rtfFNum == info->defFont)
{
if (info->ansiCodePage != CP_UTF8)
info->codePage = fp->rtfFCodePage;
TRACE("default font codepage %d\n", info->codePage);
}
}
if (fp->rtfFNum == -1)
ERR( "%s: missing font number\n", fn);
/*
* Could check other pieces of structure here, too, I suppose.
*/
RTFRouteToken (info); /* feed "}" back to router */
/* Set default font */
info->rtfClass = rtfControl;
info->rtfMajor = rtfCharAttr;
info->rtfMinor = rtfFontNum;
info->rtfParam = info->defFont;
lstrcpyA(info->rtfTextBuf, "f");
RTFUngetToken(info);
}
/*
* The color table entries have color values of -1 if
* the default color should be used for the entry (only
* a semi-colon is given in the definition, no color values).
* There will be a problem if a partial entry (1 or 2 but
* not 3 color values) is given. The possibility is ignored
* here.
*/
static void ReadColorTbl(RTF_Info *info)
{
RTFColor *cp;
int cnum = 0;
const char *fn = "ReadColorTbl";
int group_level = 1;
for (;;)
{
RTFGetToken (info);
if (info->rtfClass == rtfEOF)
break;
if (RTFCheckCM (info, rtfGroup, rtfEndGroup))
{
group_level--;
if (!group_level)
break;
continue;
}
else if (RTFCheckCM(info, rtfGroup, rtfBeginGroup))
{
group_level++;
continue;
}
cp = New (RTFColor);
if (cp == NULL)
ERR ( "%s: cannot allocate color entry\n", fn);
cp->rtfCNum = cnum++;
cp->rtfCRed = cp->rtfCGreen = cp->rtfCBlue = -1;
cp->rtfNextColor = info->colorList;
info->colorList = cp;
while (RTFCheckCM (info, rtfControl, rtfColorName))
{
switch (info->rtfMinor)
{
case rtfRed: cp->rtfCRed = info->rtfParam; break;
case rtfGreen: cp->rtfCGreen = info->rtfParam; break;
case rtfBlue: cp->rtfCBlue = info->rtfParam; break;
}
RTFGetToken (info);
}
if (info->rtfClass == rtfEOF)
break;
if (!RTFCheckCM (info, rtfText, ';'))
ERR ("%s: malformed entry\n", fn);
}
RTFRouteToken (info); /* feed "}" back to router */
}
/*
* The "Normal" style definition doesn't contain any style number,
* all others do. Normal style is given style rtfNormalStyleNum.
*/
static void ReadStyleSheet(RTF_Info *info)
{
RTFStyle *sp;
RTFStyleElt *sep, *sepLast;
char buf[rtfBufSiz], *bp;
const char *fn = "ReadStyleSheet";
int real_style;
for (;;)
{
RTFGetToken (info);
if (info->rtfClass == rtfEOF)
break;
if (RTFCheckCM (info, rtfGroup, rtfEndGroup))
break;
sp = New (RTFStyle);
if (sp == NULL)
ERR ( "%s: cannot allocate stylesheet entry\n", fn);
sp->rtfSName = NULL;
sp->rtfSNum = -1;
sp->rtfSType = rtfParStyle;
sp->rtfSAdditive = 0;
sp->rtfSBasedOn = rtfNoStyleNum;
sp->rtfSNextPar = -1;
sp->rtfSSEList = sepLast = NULL;
sp->rtfNextStyle = info->styleList;
sp->rtfExpanding = 0;
info->styleList = sp;
if (!RTFCheckCM (info, rtfGroup, rtfBeginGroup))
ERR ( "%s: missing \"{\"\n", fn);
real_style = TRUE;
for (;;)
{
RTFGetToken (info);
if (info->rtfClass == rtfEOF
|| RTFCheckCM (info, rtfText, ';'))
break;
if (info->rtfClass == rtfControl)
{
if (RTFCheckMM (info, rtfSpecialChar, rtfOptDest)) {
RTFGetToken(info);
ERR( "%s: skipping optional destination\n", fn);
RTFSkipGroup(info);
info->rtfClass = rtfGroup;
info->rtfMajor = rtfEndGroup;
real_style = FALSE;
break; /* ignore "\*" */
}
if (RTFCheckMM (info, rtfParAttr, rtfStyleNum))
{
sp->rtfSNum = info->rtfParam;
sp->rtfSType = rtfParStyle;
continue;
}
if (RTFCheckMM (info, rtfCharAttr, rtfCharStyleNum))
{
sp->rtfSNum = info->rtfParam;
sp->rtfSType = rtfCharStyle;
continue;
}
if (RTFCheckMM (info, rtfSectAttr, rtfSectStyleNum))
{
sp->rtfSNum = info->rtfParam;
sp->rtfSType = rtfSectStyle;
continue;
}
if (RTFCheckMM (info, rtfStyleAttr, rtfBasedOn))
{
sp->rtfSBasedOn = info->rtfParam;
continue;
}
if (RTFCheckMM (info, rtfStyleAttr, rtfAdditive))
{
sp->rtfSAdditive = 1;
continue;
}
if (RTFCheckMM (info, rtfStyleAttr, rtfNext))
{
sp->rtfSNextPar = info->rtfParam;
continue;
}
sep = New (RTFStyleElt);
if (sep == NULL)
ERR ( "%s: cannot allocate style element\n", fn);
sep->rtfSEClass = info->rtfClass;
sep->rtfSEMajor = info->rtfMajor;
sep->rtfSEMinor = info->rtfMinor;
sep->rtfSEParam = info->rtfParam;
sep->rtfSEText = RTFStrSave (info->rtfTextBuf);
if (sep->rtfSEText == NULL)
ERR ( "%s: cannot allocate style element text\n", fn);
if (sepLast == NULL)
sp->rtfSSEList = sep; /* first element */
else /* add to end */
sepLast->rtfNextSE = sep;
sep->rtfNextSE = NULL;
sepLast = sep;
}
else if (RTFCheckCM (info, rtfGroup, rtfBeginGroup))
{
/*
* This passes over "{\*\keycode ... }, among
* other things. A temporary (perhaps) hack.
*/
ERR( "%s: skipping begin\n", fn);
RTFSkipGroup (info);
continue;
}
else if (info->rtfClass == rtfText) /* style name */
{
bp = buf;
while (info->rtfClass == rtfText)
{
if (info->rtfMajor == ';')
{
/* put back for "for" loop */
RTFUngetToken (info);
break;
}
*bp++ = info->rtfMajor;
RTFGetToken (info);
}
*bp = '\0';
sp->rtfSName = RTFStrSave (buf);
if (sp->rtfSName == NULL)
ERR ( "%s: cannot allocate style name\n", fn);
}
else /* unrecognized */
{
/* ignore token but announce it */
WARN ( "%s: unknown token \"%s\"\n",
fn, info->rtfTextBuf);
}
}
if (real_style) {
RTFGetToken (info);
if (!RTFCheckCM (info, rtfGroup, rtfEndGroup))
ERR ( "%s: missing \"}\"\n", fn);
/*
* Check over the style structure. A name is a must.
* If no style number was specified, check whether it's the
* Normal style (in which case it's given style number
* rtfNormalStyleNum). Note that some "normal" style names
* just begin with "Normal" and can have other stuff following,
* e.g., "Normal,Times 10 point". Ugh.
*
* Some German RTF writers use "Standard" instead of "Normal".
*/
if (sp->rtfSName == NULL)
ERR ( "%s: missing style name\n", fn);
if (sp->rtfSNum < 0)
{
if (strncmp (buf, "Normal", 6) != 0
&& strncmp (buf, "Standard", 8) != 0)
ERR ( "%s: missing style number\n", fn);
sp->rtfSNum = rtfNormalStyleNum;
}
if (sp->rtfSNextPar == -1) /* if \snext not given, */
sp->rtfSNextPar = sp->rtfSNum; /* next is itself */
}
/* otherwise we're just dealing with fake end group from skipped group */
}
RTFRouteToken (info); /* feed "}" back to router */
}
static void ReadInfoGroup(RTF_Info *info)
{
RTFSkipGroup (info);
RTFRouteToken (info); /* feed "}" back to router */
}
static void ReadPictGroup(RTF_Info *info)
{
RTFSkipGroup (info);
RTFRouteToken (info); /* feed "}" back to router */
}
static void ReadObjGroup(RTF_Info *info)
{
RTFSkipGroup (info);
RTFRouteToken (info); /* feed "}" back to router */
}
/* ---------------------------------------------------------------------- */
/*
* Routines to return pieces of stylesheet, or font or color tables.
* References to style 0 are mapped onto the Normal style.
*/
RTFStyle *RTFGetStyle(RTF_Info *info, int num)
{
RTFStyle *s;
if (num == -1)
return (info->styleList);
for (s = info->styleList; s != NULL; s = s->rtfNextStyle)
{
if (s->rtfSNum == num)
break;
}
return (s); /* NULL if not found */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -