📄 rtf.c
字号:
/************************************************************************ * IRC - Internet Relay Chat, win32/rtf.c * Copyright (C) 2004 Dominick Meglio (codemastr) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 1, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <windows.h>#include "win32.h"#include "sys.h"#include "common.h"#include "struct.h"#include "h.h"unsigned char *RTFBuf;#define MIRC_COLORS "{\\colortbl;\\red255\\green255\\blue255;\\red0\\green0\\blue127;\\red0\\green147\\blue0;\\red255\\green0\\blue0;\\red127\\green0\\blue0;\\red156\\green0\\blue156;\\red252\\green127\\blue0;\\red255\\green255\\blue0;\\red0\\green252\\blue0;\\red0\\green147\\blue147;\\red0\\green255\\blue255;\\red0\\green0\\blue252;\\red255\\green0\\blue255;\\red127\\green127\\blue127;\\red210\\green210\\blue210;\\red0\\green0\\blue0;}"/* Splits the file up for the EM_STREAMIN message * Parameters: * dwCookie - The file information to split * pbBuff - The output buffer * cb - The size of pbBuff * pcb - The total bytes written to bpBuff * Returns: * Returns 0 to indicate success */DWORD CALLBACK SplitIt(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) { StreamIO *stream = (StreamIO*)dwCookie; if (*stream->size == 0) { pcb = 0; *stream->buffer = 0; } else if (cb <= *stream->size) { memcpy(pbBuff, *stream->buffer, cb); *stream->buffer += cb; *stream->size -= cb; *pcb = cb; } else { memcpy(pbBuff, *stream->buffer, *stream->size); *pcb = *stream->size; *stream->size = 0; } return 0;}/* Reassembles the RTF buffer from EM_STREAMOUT * Parameters: * dwCookie - Unused * pbBuff - The input buffer * cb - The length of the input buffer * pcb - The total bytes read from pbBuff * Returns: * 0 to indicate success * Side Effects: * RTFBuf contains the assembled RTF buffer */DWORD CALLBACK BufferIt(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) { unsigned char *buf2; static long size = 0; if (!RTFBuf) size = 0; buf2 = MyMalloc(size+cb+1); if (RTFBuf) memcpy(buf2,RTFBuf,size); memcpy(buf2+size,pbBuff,cb); size += cb; if (RTFBuf) MyFree(RTFBuf); RTFBuf = buf2; pcb = &cb; return 0;}/* Pushes a color onto the stack * Parameters: * color - The color to add to the stack * stack - The stack to add the color to */void ColorPush(unsigned char *color, IRCColor **stack){ IRCColor *t = MyMallocEx(sizeof(IRCColor)); t->color = strdup(color); t->next = *stack; (*stack) = t;}/* Pops a color off of the stack * Parameters: * stack - The stack to pop from */void ColorPop(IRCColor **stack){ IRCColor *p = *stack; if (!(*stack)) return; MyFree(p->color); *stack = p->next; MyFree(p);}/* Completely empties the color stack * Parameters: * stack - The stack to empty */void ColorEmpty(IRCColor **stack){ IRCColor *t, *next; for (t = *stack; t; t = next) { next = t->next; MyFree(t->color); MyFree(t); }}#define iseol(x) ((x) == '\r' || (x) == '\n')/* Converts a string in RTF format to IRC codes * Parameters: * fd - The file descriptor to write to * pbBuff - The buffer containing the RTF text * cb - The length of the RTF text */DWORD CALLBACK RTFToIRC(int fd, unsigned char *pbBuff, long cb) { unsigned char *buffer = malloc(cb*2); int colors[17], bold = 0, uline = 0, incolor = 0, inbg = 0; int lastwascf = 0, lastwascf0 = 0; int i = 0; IRCColor *TextColors = NULL; IRCColor *BgColors = NULL; bzero(buffer, cb); for (; *pbBuff; pbBuff++) { if (iseol(*pbBuff) || *pbBuff == '{' || *pbBuff == '}') continue; else if (*pbBuff == '\\') { /* RTF control sequence */ pbBuff++; if (*pbBuff == '\\' || *pbBuff == '{' || *pbBuff == '}') buffer[i++] = *pbBuff; else if (*pbBuff == '\'') { /* Extended ASCII character */ unsigned char ltr, ultr[3]; ultr[0] = *(++pbBuff); ultr[1] = *(++pbBuff); ultr[2] = 0; ltr = strtoul(ultr,NULL,16); buffer[i++] = ltr; } else { int j; char cmd[128]; /* Capture the control sequence */ for (j = 0; *pbBuff && *pbBuff != '\\' && !isspace(*pbBuff) && !iseol(*pbBuff); pbBuff++) { cmd[j++] = *pbBuff; } if (*pbBuff != ' ') pbBuff--; cmd[j] = 0; if (!strcmp(cmd, "fonttbl{")) { /* Eat the parameter */ while (*pbBuff && *pbBuff != '}') pbBuff++; lastwascf = lastwascf0 = 0; } if (!strcmp(cmd, "colortbl")) { char color[128]; int k = 0, m = 1; /* Capture the color table */ while (*pbBuff && !isalnum(*pbBuff)) pbBuff++; for (; *pbBuff && *pbBuff != '}'; pbBuff++) { if (*pbBuff == ';') { color[k]=0; if (!strcmp(color, "\\red255\\green255\\blue255")) colors[m++] = 0; else if (!strcmp(color, "\\red0\\green0\\blue0")) colors[m++] = 1; else if (!strcmp(color, "\\red0\\green0\\blue127")) colors[m++] = 2; else if (!strcmp(color, "\\red0\\green147\\blue0")) colors[m++] = 3; else if (!strcmp(color, "\\red255\\green0\\blue0")) colors[m++] = 4; else if (!strcmp(color, "\\red127\\green0\\blue0")) colors[m++] = 5; else if (!strcmp(color, "\\red156\\green0\\blue156")) colors[m++] = 6; else if (!strcmp(color, "\\red252\\green127\\blue0")) colors[m++] = 7; else if (!strcmp(color, "\\red255\\green255\\blue0")) colors[m++] = 8; else if (!strcmp(color, "\\red0\\green252\\blue0")) colors[m++] = 9; else if (!strcmp(color, "\\red0\\green147\\blue147")) colors[m++] = 10; else if (!strcmp(color, "\\red0\\green255\\blue255")) colors[m++] = 11; else if (!strcmp(color, "\\red0\\green0\\blue252")) colors[m++] = 12; else if (!strcmp(color, "\\red255\\green0\\blue255")) colors[m++] = 13; else if (!strcmp(color, "\\red127\\green127\\blue127")) colors[m++] = 14; else if (!strcmp(color, "\\red210\\green210\\blue210")) colors[m++] = 15; k=0; } else color[k++] = *pbBuff; } lastwascf = lastwascf0 = 0; } else if (!strcmp(cmd, "tab")) { buffer[i++] = '\t'; lastwascf = lastwascf0 = 0; } else if (!strcmp(cmd, "par")) { if (bold || uline || incolor || inbg) buffer[i++] = '\17'; buffer[i++] = '\r'; buffer[i++] = '\n'; if (!*(pbBuff+3) || *(pbBuff+3) != '}') { if (bold) buffer[i++] = '\2'; if (uline) buffer[i++] = '\37'; if (incolor) { buffer[i++] = '\3'; strcat(buffer, TextColors->color); i += strlen(TextColors->color); if (inbg) { buffer[i++] = ','; strcat(buffer, BgColors->color); i += strlen(BgColors->color); } } else if (inbg) { buffer[i++] = '\3'; buffer[i++] = '0'; buffer[i++] = '1'; buffer[i++] = ','; strcat(buffer, BgColors->color); i += strlen(BgColors->color); } } } else if (!strcmp(cmd, "b")) { bold = 1; buffer[i++] = '\2'; lastwascf = lastwascf0 = 0; } else if (!strcmp(cmd, "b0")) { bold = 0; buffer[i++] = '\2'; lastwascf = lastwascf0 = 0; } else if (!strcmp(cmd, "ul")) { uline = 1; buffer[i++] = '\37'; lastwascf = lastwascf0 = 0; } else if (!strcmp(cmd, "ulnone")) { uline = 0; buffer[i++] = '\37'; lastwascf = lastwascf0 = 0; } else if (!strcmp(cmd, "cf0")) { lastwascf0 = 1; lastwascf = 0; } else if (!strcmp(cmd, "highlight0")) { inbg = 0; ColorPop(&BgColors); buffer[i++] = '\3'; if (lastwascf0) { incolor = 0; ColorPop(&TextColors); lastwascf0 = 0; } else if (incolor) { strcat(buffer, TextColors->color); i += strlen(TextColors->color); buffer[i++] = ','; buffer[i++] = '0'; buffer[i++] = '0'; } lastwascf = lastwascf0 = 0; } else if (!strncmp(cmd, "cf", 2)) { unsigned char number[3]; int num; incolor = 1; strcpy(number, &cmd[2]); num = atoi(number); buffer[i++] = '\3'; if (colors[num] < 10) sprintf(number, "0%d", colors[num]); else sprintf(number, "%d", colors[num]); ColorPush(number, &TextColors); strcat(buffer,number); i += strlen(number); lastwascf = 1; lastwascf0 = 0; } else if (!strncmp(cmd, "highlight", 9)) { int num; unsigned char number[3]; inbg = 1; num = atoi(&cmd[9]); if (colors[num] < 10) sprintf(number, "0%d", colors[num]); else sprintf(number, "%d", colors[num]); if (incolor && !lastwascf) { buffer[i++] = '\3'; strcat(buffer, TextColors->color); i += strlen(TextColors->color); } else if (!incolor) { buffer[i++] = '\3'; buffer[i++] = '0'; buffer[i++] = '1'; } buffer[i++] = ','; strcat(buffer, number); i += strlen(number); ColorPush(number, &BgColors); lastwascf = lastwascf0 = 0; } else lastwascf = lastwascf0 = 0; if (lastwascf0 && incolor) { incolor = 0; ColorPop(&TextColors); buffer[i++] = '\3'; } } } else { lastwascf = lastwascf0 = 0; buffer[i++] = *pbBuff; } } write(fd, buffer, i); close(fd); ColorEmpty(&TextColors); ColorEmpty(&BgColors); return 0;}/* Determines the size of the buffer needed to convert IRC codes to RTF * Parameters: * buffer - The input buffer with IRC codes * Returns: * The lenght of the buffer needed to store the RTF translation */int CountRTFSize(unsigned char *buffer) { int size = 0; char bold = 0, uline = 0, incolor = 0, inbg = 0, reverse = 0; char *buf = buffer; for (; *buf; buf++) { if (*buf == '{' || *buf == '}' || *buf == '\\') size++; else if (*buf == '\r') { if (*(buf+1) && *(buf+1) == '\n') { buf++; if (bold) size += 3; if (uline) size += 7; if (incolor && !reverse) size += 4; if (inbg && !reverse) size += 11;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -