PDF转WORD开发分享系列---Sumatrapdf研究(1)---pdf_run_keyword

Posted by 代码苦力 on August 14, 2014

pdf_run_keyword

pdf_run_keyword是sumatrapdf里一个相当重要的函数, 该函数执行pdf操作符的解析功能, 一些比较重要的PDF流指令都是在该函数里完成解析并执行操作的. 诸如'Tj'操作符(该操作符用于显示字符串)其对应的处理代码段为: case B('T','j'): pdf_run_Tj(csi); break;
 
pdf_run_keyword是一个大的switch case语句, 该函数首先解析pdf流里的指令, 然后与pdf流指令码进行case比对, 并执行相应操作, 其代码内容如下(摘抄自Sumatrapdf源码):
 
fz_context *ctx = csi->dev->ctx;
int key;
 
key = buf[0];
if (buf[1])
{
key |= buf[1] << 8;
if (buf[2])
{
key |= buf[2] << 16;
if (buf[3])
key = 0;
}
}
 
switch (key)
{
case A('"'): pdf_run_dquote(csi); break;
case A('\''): pdf_run_squote(csi); break;
case A('B'): pdf_run_B(csi); break;
case B('B','*'): pdf_run_Bstar(csi); break;
case C('B','D','C'): pdf_run_BDC(csi, rdb); break;
case B('B','I'):
pdf_run_BI(csi, rdb, file);
break;
case C('B','M','C'): pdf_run_BMC(csi); break;
case B('B','T'): pdf_run_BT(csi); break;
case B('B','X'): pdf_run_BX(csi); break;
case B('C','S'): pdf_run_CS(csi, rdb); break;
case B('D','P'): pdf_run_DP(csi); break;
case B('D','o'):
fz_try(ctx)
{
pdf_run_Do(csi, rdb);
}
fz_catch(ctx)
{
fz_rethrow_message(ctx, "cannot draw xobject/image");
}
break;
case C('E','M','C'): pdf_run_EMC(csi); break;
case B('E','T'): pdf_run_ET(csi); break;
case B('E','X'): pdf_run_EX(csi); break;
case A('F'): pdf_run_F(csi); break;
case A('G'): pdf_run_G(csi); break;
case A('J'): pdf_run_J(csi); break;
case A('K'): pdf_run_K(csi); break;
case A('M'): pdf_run_M(csi); break;
case B('M','P'): pdf_run_MP(csi); break;
case A('Q'): pdf_run_Q(csi); break;
case B('R','G'): pdf_run_RG(csi); break;
case A('S'): pdf_run_S(csi); break;
case B('S','C'): pdf_run_SC(csi, rdb); break;
case C('S','C','N'): pdf_run_SC(csi, rdb); break;
case B('T','*'): pdf_run_Tstar(csi); break;
case B('T','D'): pdf_run_TD(csi); break;
case B('T','J'): pdf_run_TJ(csi); break;
case B('T','L'): pdf_run_TL(csi); break;
case B('T','c'): pdf_run_Tc(csi); break;
case B('T','d'): pdf_run_Td(csi); break;
case B('T','f'):
fz_try(ctx)
{
pdf_run_Tf(csi, rdb);
}
fz_catch(ctx)
{
fz_rethrow_message(ctx, "cannot set font");
}
break;
case B('T','j'): pdf_run_Tj(csi); break;
case B('T','m'): pdf_run_Tm(csi); break;
case B('T','r'): pdf_run_Tr(csi); break;
case B('T','s'): pdf_run_Ts(csi); break;
case B('T','w'): pdf_run_Tw(csi); break;
case B('T','z'): pdf_run_Tz(csi); break;
case A('W'): pdf_run_W(csi); break;
case B('W','*'): pdf_run_Wstar(csi); break;
case A('b'): pdf_run_b(csi); break;
case B('b','*'): pdf_run_bstar(csi); break;
case A('c'): pdf_run_c(csi); break;
case B('c','m'): pdf_run_cm(csi); break;
case B('c','s'): pdf_run_cs(csi, rdb); break;
case A('d'): pdf_run_d(csi); break;
case B('d','0'): pdf_run_d0(csi); break;
case B('d','1'): pdf_run_d1(csi); break;
case A('f'): pdf_run_f(csi); break;
case B('f','*'): pdf_run_fstar(csi); break;
case A('g'): pdf_run_g(csi); break;
case B('g','s'):
fz_try(ctx)
{
pdf_run_gs(csi, rdb);
}
fz_catch(ctx)
{
fz_rethrow_message(ctx, "cannot set graphics state");
}
break;
case A('h'): pdf_run_h(csi); break;
case A('i'): pdf_run_i(csi); break;
case A('j'): pdf_run_j(csi); break;
case A('k'): pdf_run_k(csi); break;
case A('l'): pdf_run_l(csi); break;
case A('m'): pdf_run_m(csi); break;
case A('n'): pdf_run_n(csi); break;
case A('q'): pdf_run_q(csi); break;
case B('r','e'): pdf_run_re(csi); break;
case B('r','g'): pdf_run_rg(csi); break;
case B('r','i'): pdf_run_ri(csi); break;
case A('s'): pdf_run(csi); break;
case B('s','c'): pdf_run_sc(csi, rdb); break;
case C('s','c','n'): pdf_run_sc(csi, rdb); break;
case B('s','h'):
fz_try(ctx)
{
pdf_run_sh(csi, rdb);
}
fz_catch(ctx)
{
fz_rethrow_message(ctx, "cannot draw shading");
}
break;
case A('v'): pdf_run_v(csi); break;
case A('w'): pdf_run_w(csi); break;
case A('y'): pdf_run_y(csi); break;
default:
if (!csi->xbalance)
{
fz_warn(ctx, "unknown keyword: '%s'", buf);
return 1;
}
break;
}
 
 
pdf_run_keyword的在Sumatrapdf里的调用堆栈如下:
 
PdfEngineImpl::RunPage
pdf_run_page_with_usage
pdf_run_page_contents_with_usage
pdf_run_contents_object
pdf_run_contents_stream
pdf_run_stream
pdf_run_keyword
 
 
 
 
 

Editor's Picks