⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 script_enc.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
	} 	GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "recieved", id);	gf_list_add(sc_enc->identifiers, strdup(id));	gf_bifs_enc_name(sc_enc->codec, sc_enc->bs, id);}void SFE_Arguments(ScriptEnc *sc_enc){	while (1) {		if (!SFE_NextToken(sc_enc)) return;		if (sc_enc->token_code == TOK_RIGHT_CURVE) break;		else if (sc_enc->token_code == TOK_COMMA) continue;		GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "hasArgument", NULL);		SFE_PutIdentifier(sc_enc, sc_enc->token);	}	GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "hasArgument", NULL);}void SFE_StatementBlock(ScriptEnc *sc_enc);void SFE_Statement(ScriptEnc *sc_enc);void SFE_PutInteger(ScriptEnc *sc_enc, char *str){	u32 nbBits, val = 0;	if (sc_enc->emul) return;	if ((str[0]=='0') && (str[1]=='x' || str[1]=='X')) {		val = strtoul(sc_enc->token, (char **) NULL, 16);	} else if (str[0]=='0' && isdigit(str[1])) {		val = strtoul(str, (char **) NULL, 8);	} else if (isdigit(str[0])) {		val = strtoul(str, (char **) NULL, 10);	} else {		GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: %s is not an integer\n", str));		sc_enc->err = GF_BAD_PARAM;		return;	}	nbBits = gf_get_bit_size(val);	GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, nbBits, 5, "nbBitsInteger", NULL);	GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, val, nbBits, "value", sc_enc->token);}u32 SFE_LoadExpression(ScriptEnc *sc_enc, u32 *expr_sep){	Bool is_var = 0;	u32 close_code, open_code;	u32 count = 0;	u32 nbExpr = 1;	u32 nbIndir = 0;	expr_sep[0] = 0;		sc_enc->expr_toks_len = 0;	while ( (sc_enc->token_code != TOK_SEMICOLON) && (sc_enc->token_code != TOK_RIGHT_CURVE) ) {		switch (sc_enc->token_code) {		case TOK_CONDTEST:			nbIndir ++;			break;		case TOK_CONDSEP:			if (nbIndir > 0) nbIndir--;			/*'case'*/			else {				goto break_loop;			}			break;		case TOK_IDENTIFIER:		case TOK_NUMBER:		case TOK_STRING:		case TOK_BOOLEAN:			gf_list_add(sc_enc->id_buf, strdup(sc_enc->token));			break;		case TOK_FUNCTION:			goto break_loop;		}		if (sc_enc->token_code==TOK_VAR) is_var = 1;		if (!is_var || (sc_enc->token_code!=TOK_COMMA)) {			sc_enc->expr_toks[sc_enc->expr_toks_len] = sc_enc->token_code;			sc_enc->expr_toks_len++;		}		open_code = sc_enc->token_code;		close_code = 0;		if (sc_enc->token_code == TOK_LEFT_CURVE) close_code = TOK_RIGHT_CURVE;		else if (sc_enc->token_code == TOK_LEFT_BRACKET) close_code = TOK_RIGHT_BRACKET;		else if (sc_enc->token_code == TOK_LEFT_BRACE) close_code = TOK_RIGHT_BRACE;		/*other expr*/		if ((sc_enc->token_code == TOK_COMMA) && (sc_enc->expr_toks[0] != TOK_VAR) ){			expr_sep[nbExpr++] = sc_enc->expr_toks_len - 1;		} 		/*sub-expr*/		else if (close_code) {			count++;			do {				SFE_NextToken(sc_enc);				if ((sc_enc->token_code == TOK_IDENTIFIER) || (sc_enc->token_code == TOK_NUMBER) 					|| (sc_enc->token_code == TOK_STRING) || (sc_enc->token_code == TOK_BOOLEAN) ) {					gf_list_add(sc_enc->id_buf, strdup(sc_enc->token));				}				sc_enc->expr_toks[sc_enc->expr_toks_len] = sc_enc->token_code;				sc_enc->expr_toks_len++;				if (sc_enc->token_code == open_code) count++;				else if (sc_enc->token_code == close_code) count--;			} while ( (sc_enc->token_code != close_code) || count);		}		SFE_NextToken(sc_enc);	}break_loop:	if (sc_enc->err) {		GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: end of compoundExpression not found\n"));		return 0;	}	expr_sep[nbExpr] = sc_enc->expr_toks_len;	if ((sc_enc->token_code == TOK_IDENTIFIER) || (sc_enc->token_code == TOK_NUMBER) 		|| (sc_enc->token_code == TOK_STRING) || (sc_enc->token_code == TOK_BOOLEAN) ) {		gf_list_add(sc_enc->id_buf, strdup(sc_enc->token));	}		if ((sc_enc->token_code != TOK_CONDSEP) && (sc_enc->token_code != TOK_RIGHT_BRACE) && (sc_enc->expr_toks[0] != TOK_VAR)) {		sc_enc->expr_toks[sc_enc->expr_toks_len] = sc_enc->token_code;		sc_enc->expr_toks_len++;	}	return nbExpr;}u32 MoveToToken(ScriptEnc *sc_enc, u32 endTok, u32 cur, u32 end);u32 SFE_ScanExpression(ScriptEnc *sc_enc, u32 start, u32 end, u32 *expr_sep){	u32 curTok;	u32 n = start;	u32 nbExpr = 1;	expr_sep[0] = start;	while (n<end) {		curTok = sc_enc->expr_toks[n++];		if (curTok == TOK_LEFT_CURVE) {			n = MoveToToken(sc_enc, TOK_RIGHT_CURVE, n-1, end);			n++;		} else if (curTok == TOK_LEFT_BRACKET) {			n = MoveToToken(sc_enc, TOK_RIGHT_BRACKET, n-1, end);			n++;		} else if (curTok == TOK_COMMA) {			expr_sep[nbExpr++] = n-1;		}	}	expr_sep[nbExpr] = end;	return nbExpr;}u32 SFE_Expression(ScriptEnc *sc_enc, u32 start, u32 end, Bool memberAccess);void SFE_CompoundExpression(ScriptEnc *sc_enc, u32 start, u32 end, u32 isPar){	u32 nbExp, i;	/*filled by indexes of ',' expressions in the expr_tok buffer*/	u32 expr_sep[MAX_NUM_EXPR];	if (sc_enc->err) return;	if (end==0) {		/*load expressions , eg "a ? ((a>b) ? 1 : 0) : 0" */		nbExp = SFE_LoadExpression(sc_enc, expr_sep);	} else {		/*load sub-expression from loaded expression set*/		nbExp = SFE_ScanExpression(sc_enc, start, end, expr_sep);	}	SFE_Expression(sc_enc, expr_sep[0], expr_sep[1], 0);	for (i=1; i<nbExp; i++) {		SFE_WRITE_INT(sc_enc, 1, 1, isPar ? "hasParam" : "hasExpression", NULL);		SFE_Expression(sc_enc, expr_sep[i]+1, expr_sep[i+1], 0);	}	SFE_WRITE_INT(sc_enc, 0, 1, isPar ? "hasParam" : "hasExpression", NULL);}void SFE_OptionalExpression(ScriptEnc *sc_enc){	if (sc_enc->token_code != TOK_SEMICOLON) {		SFE_WRITE_INT(sc_enc, 1, 1, "hasCompoundExpression", NULL);		SFE_CompoundExpression(sc_enc, 0, 0, 0);	} else {		SFE_WRITE_INT(sc_enc, 0, 1, "hasCompoundExpression", NULL);	}}void SFE_IfStatement(ScriptEnc *sc_enc){	char *buf_bck;	u32 tok_bck;	SFE_NextToken(sc_enc);	SFE_CheckToken(sc_enc, TOK_LEFT_CURVE);	SFE_NextToken(sc_enc);	SFE_CompoundExpression(sc_enc, 0, 0, 0);	SFE_CheckToken(sc_enc, TOK_RIGHT_CURVE);	SFE_StatementBlock(sc_enc);	buf_bck = sc_enc->cur_buf;	tok_bck = sc_enc->token_code;	SFE_NextToken(sc_enc);	if (sc_enc->token_code == TOK_ELSE) {		SFE_WRITE_INT(sc_enc, 1, 1, "hasELSEStatement", NULL);		SFE_StatementBlock(sc_enc);	} else {		SFE_WRITE_INT(sc_enc, 0, 1, "hasELSEStatement", NULL);		sc_enc->cur_buf = buf_bck;		sc_enc->token_code = tok_bck;	}}void SFE_ForStatement(ScriptEnc *sc_enc){	SFE_NextToken(sc_enc);	SFE_CheckToken(sc_enc, TOK_LEFT_CURVE);	SFE_NextToken(sc_enc);	SFE_OptionalExpression(sc_enc);	SFE_CheckToken(sc_enc, TOK_SEMICOLON);		SFE_NextToken(sc_enc);	SFE_OptionalExpression(sc_enc);	SFE_CheckToken(sc_enc, TOK_SEMICOLON);		SFE_NextToken(sc_enc);	SFE_OptionalExpression(sc_enc);	SFE_CheckToken(sc_enc, TOK_RIGHT_CURVE);	SFE_StatementBlock(sc_enc);}void SFE_WhileStatement(ScriptEnc *sc_enc){	SFE_NextToken(sc_enc);	SFE_CheckToken(sc_enc, TOK_LEFT_CURVE);	SFE_NextToken(sc_enc);	SFE_CompoundExpression(sc_enc, 0, 0, 0);	SFE_CheckToken(sc_enc, TOK_RIGHT_CURVE);	SFE_StatementBlock(sc_enc);}void SFE_ReturnStatement(ScriptEnc *sc_enc){	SFE_NextToken(sc_enc);	if (sc_enc->token_code != TOK_SEMICOLON) {		SFE_WRITE_INT(sc_enc, 1, 1, "returnValue", NULL);		SFE_CompoundExpression(sc_enc, 0, 0, 0);	} else {		SFE_WRITE_INT(sc_enc, 0, 1, "returnValue", NULL);	}}void SFE_CaseBlock(ScriptEnc *sc_enc){	SFE_WRITE_INT(sc_enc, 1, 1, "isCompoundStatement", NULL);	SFE_NextToken(sc_enc);	if (sc_enc->token_code == TOK_LEFT_BRACE) {		SFE_NextToken(sc_enc);	    while (sc_enc->token_code != TOK_RIGHT_BRACE) {			SFE_WRITE_INT(sc_enc, 1, 1, "hasStatement", NULL);		    SFE_Statement(sc_enc);			SFE_NextToken(sc_enc);	    }		SFE_NextToken(sc_enc);	}    while ((sc_enc->token_code != TOK_CASE) && (sc_enc->token_code != TOK_DEFAULT) && (sc_enc->token_code != TOK_RIGHT_BRACE)) {		SFE_WRITE_INT(sc_enc, 1, 1, "hasStatement", NULL);		SFE_Statement(sc_enc);		SFE_NextToken(sc_enc);    }	SFE_WRITE_INT(sc_enc, 0, 1, "hasStatement", NULL);}u32 SFE_PutCaseInteger(ScriptEnc *sc_enc, char *str, u32 nbBits){	u32 val = 0;	if ((str[0]=='0') && (str[1]=='x' || str[1]=='X')) {		val = strtoul(sc_enc->token, (char **) NULL, 16);	} else if (str[0]=='0' && isdigit(str[1])) {		val = strtoul(str, (char **) NULL, 8);	} else if (isdigit(str[0])) {		val = strtoul(str, (char **) NULL, 10);	} else {		GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: %s is not an integer\n", str));		sc_enc->err = GF_BAD_PARAM;		return 0;	}	if (!sc_enc->emul) {		GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, val, nbBits, "value", sc_enc->token);	} else {		nbBits = gf_get_bit_size(val);	}	return nbBits;}void SFE_SwitchStatement(ScriptEnc *sc_enc){	u32 nbBits, maxBits = 0;	Bool prev_emu;	char *buf_bck;	u32 tok_bck;	SFE_NextToken(sc_enc);	SFE_CheckToken(sc_enc, TOK_LEFT_CURVE);	SFE_NextToken(sc_enc);	SFE_CompoundExpression(sc_enc, 0, 0, 0);	SFE_CheckToken(sc_enc, TOK_RIGHT_CURVE);	SFE_NextToken(sc_enc);	SFE_CheckToken(sc_enc, TOK_LEFT_BRACE);	/*first pass in emul*/	buf_bck = sc_enc->cur_buf;	tok_bck = sc_enc->token_code;	prev_emu = sc_enc->emul;	sc_enc->emul = 1;	SFE_NextToken(sc_enc);    while (sc_enc->token_code == TOK_CASE) {		SFE_NextToken(sc_enc);		SFE_CheckToken(sc_enc, TOK_NUMBER);		nbBits = SFE_PutCaseInteger(sc_enc, sc_enc->token, 0);		if (maxBits<nbBits) maxBits = nbBits;		SFE_NextToken(sc_enc);		SFE_CheckToken(sc_enc, TOK_CONDSEP);        SFE_CaseBlock(sc_enc);		SFE_WRITE_INT(sc_enc, (sc_enc->token_code == TOK_CASE) ? 1 : 0, 1, "hasMoreCases", NULL);    }	/*second pass in parent mode*/	sc_enc->cur_buf = buf_bck; 	sc_enc->token_code = tok_bck;	sc_enc->emul = prev_emu;	maxBits ++;	SFE_WRITE_INT(sc_enc, maxBits, 5, "caseNbBits", NULL);	SFE_NextToken(sc_enc);    while (sc_enc->token_code == TOK_CASE) {		SFE_NextToken(sc_enc);		SFE_CheckToken(sc_enc, TOK_NUMBER);		SFE_PutCaseInteger(sc_enc, sc_enc->token, maxBits);		SFE_NextToken(sc_enc);		SFE_CheckToken(sc_enc, TOK_CONDSEP);        SFE_CaseBlock(sc_enc);		SFE_WRITE_INT(sc_enc, (sc_enc->token_code == TOK_CASE) ? 1 : 0, 1, "hasMoreCases", NULL);    }    if (sc_enc->token_code == TOK_DEFAULT) {		SFE_WRITE_INT(sc_enc, 1, 1, "hasDefault", NULL);		SFE_NextToken(sc_enc);		SFE_CheckToken(sc_enc, TOK_CONDSEP);        SFE_CaseBlock(sc_enc);    } else {		SFE_WRITE_INT(sc_enc, 0, 1, "hasDefault", NULL);    }	SFE_CheckToken(sc_enc, TOK_RIGHT_BRACE);}void SFE_Statement(ScriptEnc *sc_enc){	switch (sc_enc->token_code) {	case TOK_IF:		SFE_WRITE_INT(sc_enc, ST_IF, NUMBITS_STATEMENT, "statementType", "if");		SFE_IfStatement(sc_enc);		break;	case TOK_FOR:		SFE_WRITE_INT(sc_enc, ST_FOR, NUMBITS_STATEMENT, "statementType", "for");		SFE_ForStatement(sc_enc);		break;	case TOK_WHILE:		SFE_WRITE_INT(sc_enc, ST_WHILE, NUMBITS_STATEMENT, "statementType", "while");		SFE_WhileStatement(sc_enc);		break;	case TOK_RETURN:		SFE_WRITE_INT(sc_enc, ST_RETURN, NUMBITS_STATEMENT, "statementType", "return");		SFE_ReturnStatement(sc_enc);		break;	case TOK_BREAK:		SFE_WRITE_INT(sc_enc, ST_BREAK, NUMBITS_STATEMENT, "statementType", "break");		SFE_NextToken(sc_enc);		break;	case TOK_CONTINUE:		SFE_WRITE_INT(sc_enc, ST_CONTINUE, NUMBITS_STATEMENT, "statementType", "continue");		SFE_NextToken(sc_enc);		break;	case TOK_SWITCH:		SFE_WRITE_INT(sc_enc, ST_SWITCH, NUMBITS_STATEMENT, "statementType", "while");		SFE_SwitchStatement(sc_enc);		break;	default:		SFE_WRITE_INT(sc_enc, ST_COMPOUND_EXPR, NUMBITS_STATEMENT, "statementType", "compoundExpr");		SFE_CompoundExpression(sc_enc, 0, 0, 0);		break;	}}void SFE_Statements(ScriptEnc *sc_enc){	while (1) {		if (!SFE_NextToken(sc_enc)) return;		if (sc_enc->token_code == TOK_RIGHT_BRACE) break;		SFE_WRITE_INT(sc_enc, 1, 1, "hasStatement", NULL);		SFE_Statement(sc_enc);	}	SFE_WRITE_INT(sc_enc, 0, 1, "hasStatement", NULL);}void SFE_StatementBlock(ScriptEnc *sc_enc){	if (!SFE_NextToken(sc_enc)) return;	if (sc_enc->token_code == TOK_LEFT_BRACE) {		SFE_WRITE_INT(sc_enc, 1, 1, "isCompoundStatement", NULL);		SFE_Statements(sc_enc);	} else {		SFE_WRITE_INT(sc_enc, 0, 1, "isCompoundStatement", NULL);		SFE_Statement(sc_enc);	}}void SFE_Function(ScriptEnc *sc_enc){	char szName[1000];	SFE_NextToken(sc_enc);	SFE_CheckToken(sc_enc, TOK_FUNCTION);	SFE_NextToken(sc_enc);	SFE_CheckToken(sc_enc, TOK_IDENTIFIER);	strcpy(szName, sc_enc->token);	SFE_PutIdentifier(sc_enc, sc_enc->token);		SFE_NextToken(sc_enc);	SFE_CheckToken(sc_enc, TOK_LEFT_CURVE);	SFE_Arguments(sc_enc);	SFE_StatementBlock(sc_enc);	if (sc_enc->err) GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: Error while parsing function %s\n", szName));}GF_Err SFScript_Encode(GF_BifsEncoder *codec, SFScript *script_field, GF_BitStream *bs, GF_Node *n){	char *ptr;	ScriptEnc sc_enc;	if (gf_node_get_tag(n) != TAG_MPEG4_Script) return GF_NON_COMPLIANT_BITSTREAM;	memset(&sc_enc, 0, sizeof(ScriptEnc));	sc_enc.codec = codec;	sc_enc.script = n;	sc_enc.bs = bs;	sc_enc.identifiers = gf_list_new();	sc_enc.id_buf = gf_list_new();	sc_enc.err = GF_OK;	if (codec->is_encoding_command) {		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Script::isList", NULL);		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);	} else {			EncScriptFields(&sc_enc);	}	/*reserevd*/	GF_BIFS_WRITE_INT(codec, bs, 1, 1, "reserved", NULL);	if (script_field) {		sc_enc.cur_buf = (char *)script_field->script_text;	} else if (((M_Script*)n)->url.count) {		sc_enc.cur_buf = (char *)((M_Script*)n)->url.vals[0].script_text;	}	if (sc_enc.cur_buf) {		if (!strnicmp(sc_enc.cur_buf, "javascript:", 11) 			|| !strnicmp(sc_enc.cur_buf, "vrmlscript:", 11)			|| !strnicmp(sc_enc.cur_buf, "ECMAScript:", 11)			) {			sc_enc.cur_buf += 11;		} else if (!strnicmp(sc_enc.cur_buf, "mpeg4script:", 12) ) {			sc_enc.cur_buf += 12;		}	}	/*encode functions*/	while (sc_enc.cur_buf && sc_enc.cur_buf[0] && (sc_enc.cur_buf[0]!='}')) {		if (strchr("\r\n\t ", sc_enc.cur_buf[0]) ) {			sc_enc.cur_buf++;			continue;		}		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "hasFunction", NULL);		SFE_Function(&sc_enc);		if (sc_enc.err) break;	}	GF_BIFS_WRITE_INT(codec, bs, 0, 1, "hasFunction", NULL);	//clean up	while (gf_list_count(sc_enc.identifiers)) {		ptr = (char *)gf_list_get(sc_enc.identifiers, 0);		gf_list_rem(sc_enc.identifiers, 0);		free(ptr);	}	gf_list_del(sc_enc.identifiers);	/*in case of error this is needed*/	while (gf_list_count(sc_enc.id_buf)) {		ptr = (char *)gf_list_get(sc_enc.id_buf, 0);		gf_list_rem(sc_enc.id_buf, 0);		free(ptr);	}	gf_list_del(sc_enc.id_buf);		return sc_enc.err;}void SFE_PutReal(ScriptEnc *sc_enc, char *str){	u32 i, length = strlen(str);	for (i=0; i<length; i++) {		s32 c = str[i];		if (c >= '0' && c <= '9') 			{ SFE_WRITE_INT(sc_enc, c-'0', 4, "floatChar", "Digital"); }		else if (c == '.') 			{ SFE_WRITE_INT(sc_enc, 10, 4, "floatChar", "Decimal Point"); }		else if (c == 'e' || c == 'E') 			{ SFE_WRITE_INT(sc_enc, 11, 4, "floatChar", "Exponential");}		else if (c == '-') 			{SFE_WRITE_INT(sc_enc, 12, 4, "floatChar", "Sign");}		else {			GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: %s is not a real number\n", str));			sc_enc->err = GF_BAD_PARAM;			return;		}	}	SFE_WRITE_INT(sc_enc, 15, 4, "floatChar", "End Symbol");}void SFE_PutNumber(ScriptEnc *sc_enc, char *str) {   if (strpbrk(str,".eE-") == 0) {		SFE_WRITE_INT(sc_enc, 1, 1, "isInteger", "integer");		SFE_PutInteger(sc_enc, str);	} else {		SFE_WRITE_INT(sc_enc, 0, 1, "isInteger", "real");		SFE_PutReal(sc_enc, str);	}}void SFE_PutBoolean(ScriptEnc *sc_enc, char *str){    u32 v = 1;	if (!stricmp(str, "false") || !strcmp(str, "0")) v = 0;	SFE_WRITE_INT(sc_enc, v, 1, "value", "bolean");}#define CHECK_TOK(x) \	if (curTok != x) { \		GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[bifs] Script encoding: Token %s read, %s expected\n", tok_names[curTok], tok_names[x])); \		sc_enc->err = GF_BAD_PARAM;	\	}	\u32 TOK_To_ET(u32 tok){	switch(tok) {	case TOK_INCREMENT: return ET_INCREMENT;	case TOK_DECREMENT: return ET_DECREMENT;	case TOK_NOT: return ET_NOT;	case TOK_ONESCOMP: return ET_ONESCOMP;	case TOK_MULTIPLY : return ET_MULTIPLY;	case TOK_DIVIDE : return ET_DIVIDE;	case TOK_MOD : return ET_MOD;	case TOK_PLUS : return ET_PLUS;	case TOK_MINUS : return ET_MINUS;	case TOK_LSHIFT : return ET_LSHIFT;	case TOK_RSHIFT : return ET_RSHIFT;	case TOK_RSHIFTFILL : return ET_RSHIFTFILL;	case TOK_LT : return ET_LT;	case TOK_LE : return ET_LE;	case TOK_GT : return ET_GT;	case TOK_GE : return ET_GE;	case TOK_EQ : return ET_EQ;	case TOK_NE : return ET_NE;	case TOK_AND : return ET_AND;	case TOK_XOR : return ET_XOR;	case TOK_OR : return ET_OR;	case TOK_LAND : return ET_LAND;	case TOK_LOR : return ET_LOR;	case TOK_CONDTEST : return ET_CONDTEST;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -