unrealircd- supernets unrealircd source & configuration |
git clone git://git.acid.vegas/unrealircd.git |
Log | Files | Refs | Archive | README | LICENSE |
rtf.c (18912B)
1 /************************************************************************ 2 * IRC - Internet Relay Chat, windows/rtf.c 3 * Copyright (C) 2004 Dominick Meglio (codemastr) 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 1, or (at your option) 8 * any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 */ 19 20 #include "unrealircd.h" 21 #include "win.h" 22 23 unsigned char *RTFBuf; 24 25 #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;}" 26 27 /* Splits the file up for the EM_STREAMIN message 28 * Parameters: 29 * dwCookie - The file information to split 30 * pbBuff - The output buffer 31 * cb - The size of pbBuff 32 * pcb - The total bytes written to bpBuff 33 * Returns: 34 * Returns 0 to indicate success 35 */ 36 DWORD CALLBACK SplitIt(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) 37 { 38 StreamIO *stream = (StreamIO*)dwCookie; 39 if (*stream->size == 0) 40 { 41 pcb = 0; 42 *stream->buffer = 0; 43 } 44 else if (cb <= *stream->size) 45 { 46 memcpy(pbBuff, *stream->buffer, cb); 47 *stream->buffer += cb; 48 *stream->size -= cb; 49 *pcb = cb; 50 51 } 52 else 53 { 54 memcpy(pbBuff, *stream->buffer, *stream->size); 55 *pcb = *stream->size; 56 *stream->size = 0; 57 } 58 return 0; 59 } 60 61 /* Reassembles the RTF buffer from EM_STREAMOUT 62 * Parameters: 63 * dwCookie - Unused 64 * pbBuff - The input buffer 65 * cb - The length of the input buffer 66 * pcb - The total bytes read from pbBuff 67 * Returns: 68 * 0 to indicate success 69 * Side Effects: 70 * RTFBuf contains the assembled RTF buffer 71 */ 72 DWORD CALLBACK BufferIt(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) 73 { 74 unsigned char *buf2; 75 static long size = 0; 76 if (!RTFBuf) 77 size = 0; 78 79 buf2 = safe_alloc(size+cb+1); 80 81 if (RTFBuf) 82 memcpy(buf2,RTFBuf,size); 83 84 memcpy(buf2+size,pbBuff,cb); 85 86 size += cb; 87 safe_free(RTFBuf); 88 89 RTFBuf = buf2; 90 91 pcb = &cb; 92 return 0; 93 } 94 95 /* Pushes a color onto the stack 96 * Parameters: 97 * color - The color to add to the stack 98 * stack - The stack to add the color to 99 */ 100 void ColorPush(unsigned char *color, IRCColor **stack) 101 { 102 IRCColor *t = safe_alloc(sizeof(IRCColor)); 103 safe_strdup(t->color, color); 104 t->next = *stack; 105 (*stack) = t; 106 } 107 108 /* Pops a color off of the stack 109 * Parameters: 110 * stack - The stack to pop from 111 */ 112 void ColorPop(IRCColor **stack) 113 { 114 IRCColor *p = *stack; 115 if (!(*stack)) 116 return; 117 safe_free(p->color); 118 119 *stack = p->next; 120 safe_free(p); 121 } 122 123 /* Completely empties the color stack 124 * Parameters: 125 * stack - The stack to empty 126 */ 127 void ColorEmpty(IRCColor **stack) 128 { 129 IRCColor *t, *next; 130 for (t = *stack; t; t = next) 131 { 132 next = t->next; 133 safe_free(t->color); 134 safe_free(t); 135 } 136 } 137 138 #define iseol(x) ((x) == '\r' || (x) == '\n') 139 140 /* Converts a string in RTF format to IRC codes 141 * Parameters: 142 * fd - The file descriptor to write to 143 * pbBuff - The buffer containing the RTF text 144 * cb - The length of the RTF text 145 */ 146 DWORD CALLBACK RTFToIRC(int fd, unsigned char *pbBuff, long cb) 147 { 148 unsigned char *buffer = safe_alloc(cb*2+2); 149 int colors[17], bold = 0, uline = 0, incolor = 0, inbg = 0; 150 int lastwascf = 0, lastwascf0 = 0; 151 int i = 0; 152 153 IRCColor *TextColors = NULL; 154 IRCColor *BgColors = NULL; 155 156 memset(buffer, 0, cb); 157 158 for (; *pbBuff; pbBuff++) 159 { 160 if (iseol(*pbBuff) || *pbBuff == '{' || *pbBuff == '}') 161 continue; 162 else if (*pbBuff == '\\') 163 { 164 /* RTF control sequence */ 165 pbBuff++; 166 if (*pbBuff == '\\' || *pbBuff == '{' || *pbBuff == '}') 167 buffer[i++] = *pbBuff; 168 else if (*pbBuff == '\'') 169 { 170 /* Extended ASCII character */ 171 unsigned char ltr, ultr[3]; 172 ultr[0] = *(++pbBuff); 173 ultr[1] = *(++pbBuff); 174 ultr[2] = 0; 175 ltr = strtoul(ultr,NULL,16); 176 buffer[i++] = ltr; 177 } 178 else 179 { 180 int j; 181 char cmd[128]; 182 /* Capture the control sequence */ 183 for (j = 0; *pbBuff && *pbBuff != '\\' && !isspace(*pbBuff) && 184 !iseol(*pbBuff); pbBuff++) 185 { 186 cmd[j++] = *pbBuff; 187 } 188 if (*pbBuff != ' ') 189 pbBuff--; 190 cmd[j] = 0; 191 if (!strcmp(cmd, "fonttbl{")) 192 { 193 /* Eat the parameter */ 194 while (*pbBuff && *pbBuff != '}') 195 pbBuff++; 196 lastwascf = lastwascf0 = 0; 197 } 198 if (!strcmp(cmd, "colortbl")) 199 { 200 char color[128]; 201 int k = 0, m = 1; 202 /* Capture the color table */ 203 while (*pbBuff && !isalnum(*pbBuff)) 204 pbBuff++; 205 for (; *pbBuff && *pbBuff != '}'; pbBuff++) 206 { 207 if (*pbBuff == ';') 208 { 209 color[k]=0; 210 if (!strcmp(color, "\\red255\\green255\\blue255")) 211 colors[m++] = 0; 212 else if (!strcmp(color, "\\red0\\green0\\blue0")) 213 colors[m++] = 1; 214 else if (!strcmp(color, "\\red0\\green0\\blue127")) 215 colors[m++] = 2; 216 else if (!strcmp(color, "\\red0\\green147\\blue0")) 217 colors[m++] = 3; 218 else if (!strcmp(color, "\\red255\\green0\\blue0")) 219 colors[m++] = 4; 220 else if (!strcmp(color, "\\red127\\green0\\blue0")) 221 colors[m++] = 5; 222 else if (!strcmp(color, "\\red156\\green0\\blue156")) 223 colors[m++] = 6; 224 else if (!strcmp(color, "\\red252\\green127\\blue0")) 225 colors[m++] = 7; 226 else if (!strcmp(color, "\\red255\\green255\\blue0")) 227 colors[m++] = 8; 228 else if (!strcmp(color, "\\red0\\green252\\blue0")) 229 colors[m++] = 9; 230 else if (!strcmp(color, "\\red0\\green147\\blue147")) 231 colors[m++] = 10; 232 else if (!strcmp(color, "\\red0\\green255\\blue255")) 233 colors[m++] = 11; 234 else if (!strcmp(color, "\\red0\\green0\\blue252")) 235 colors[m++] = 12; 236 else if (!strcmp(color, "\\red255\\green0\\blue255")) 237 colors[m++] = 13; 238 else if (!strcmp(color, "\\red127\\green127\\blue127")) 239 colors[m++] = 14; 240 else if (!strcmp(color, "\\red210\\green210\\blue210")) 241 colors[m++] = 15; 242 k=0; 243 } 244 else 245 color[k++] = *pbBuff; 246 } 247 lastwascf = lastwascf0 = 0; 248 } 249 else if (!strcmp(cmd, "tab")) 250 { 251 buffer[i++] = '\t'; 252 lastwascf = lastwascf0 = 0; 253 } 254 else if (!strcmp(cmd, "par")) 255 { 256 if (bold || uline || incolor || inbg) 257 buffer[i++] = '\17'; 258 buffer[i++] = '\r'; 259 buffer[i++] = '\n'; 260 if (!*(pbBuff+3) || *(pbBuff+3) != '}') 261 { 262 if (bold) 263 buffer[i++] = '\2'; 264 if (uline) 265 buffer[i++] = '\37'; 266 if (incolor) 267 { 268 buffer[i++] = '\3'; 269 strcat(buffer, TextColors->color); 270 i += strlen(TextColors->color); 271 if (inbg) 272 { 273 buffer[i++] = ','; 274 strcat(buffer, BgColors->color); 275 i += strlen(BgColors->color); 276 } 277 } 278 else if (inbg) 279 { 280 buffer[i++] = '\3'; 281 buffer[i++] = '0'; 282 buffer[i++] = '1'; 283 buffer[i++] = ','; 284 strcat(buffer, BgColors->color); 285 i += strlen(BgColors->color); 286 } 287 } 288 } 289 else if (!strcmp(cmd, "b")) 290 { 291 bold = 1; 292 buffer[i++] = '\2'; 293 lastwascf = lastwascf0 = 0; 294 } 295 else if (!strcmp(cmd, "b0")) 296 { 297 bold = 0; 298 buffer[i++] = '\2'; 299 lastwascf = lastwascf0 = 0; 300 } 301 else if (!strcmp(cmd, "ul")) 302 { 303 uline = 1; 304 buffer[i++] = '\37'; 305 lastwascf = lastwascf0 = 0; 306 } 307 else if (!strcmp(cmd, "ulnone")) 308 { 309 uline = 0; 310 buffer[i++] = '\37'; 311 lastwascf = lastwascf0 = 0; 312 } 313 else if (!strcmp(cmd, "cf0")) 314 { 315 lastwascf0 = 1; 316 lastwascf = 0; 317 } 318 else if (!strcmp(cmd, "highlight0")) 319 { 320 inbg = 0; 321 ColorPop(&BgColors); 322 buffer[i++] = '\3'; 323 if (lastwascf0) 324 { 325 incolor = 0; 326 ColorPop(&TextColors); 327 lastwascf0 = 0; 328 } 329 else if (incolor) 330 { 331 strcat(buffer, TextColors->color); 332 i += strlen(TextColors->color); 333 buffer[i++] = ','; 334 buffer[i++] = '0'; 335 buffer[i++] = '0'; 336 } 337 lastwascf = lastwascf0 = 0; 338 } 339 else if (!strncmp(cmd, "cf", 2)) 340 { 341 unsigned char number[3]; 342 int num; 343 incolor = 1; 344 strcpy(number, &cmd[2]); 345 num = atoi(number); 346 buffer[i++] = '\3'; 347 if (colors[num] < 10) 348 sprintf(number, "0%d", colors[num]); 349 else 350 sprintf(number, "%d", colors[num]); 351 ColorPush(number, &TextColors); 352 strcat(buffer,number); 353 i += strlen(number); 354 lastwascf = 1; 355 lastwascf0 = 0; 356 } 357 else if (!strncmp(cmd, "highlight", 9)) 358 { 359 int num; 360 unsigned char number[3]; 361 inbg = 1; 362 num = atoi(&cmd[9]); 363 if (colors[num] < 10) 364 sprintf(number, "0%d", colors[num]); 365 else 366 sprintf(number, "%d", colors[num]); 367 if (incolor && !lastwascf) 368 { 369 buffer[i++] = '\3'; 370 strcat(buffer, TextColors->color); 371 i += strlen(TextColors->color); 372 } 373 else if (!incolor) 374 { 375 buffer[i++] = '\3'; 376 buffer[i++] = '0'; 377 buffer[i++] = '1'; 378 } 379 buffer[i++] = ','; 380 strcat(buffer, number); 381 i += strlen(number); 382 ColorPush(number, &BgColors); 383 lastwascf = lastwascf0 = 0; 384 } 385 else 386 lastwascf = lastwascf0 = 0; 387 388 if (lastwascf0 && incolor) 389 { 390 incolor = 0; 391 ColorPop(&TextColors); 392 buffer[i++] = '\3'; 393 } 394 } 395 } 396 else 397 { 398 lastwascf = lastwascf0 = 0; 399 buffer[i++] = *pbBuff; 400 } 401 402 } 403 write(fd, buffer, i); 404 close(fd); 405 ColorEmpty(&TextColors); 406 ColorEmpty(&BgColors); 407 return 0; 408 } 409 410 /* Determines the size of the buffer needed to convert IRC codes to RTF 411 * Parameters: 412 * buffer - The input buffer with IRC codes 413 * Returns: 414 * The lenght of the buffer needed to store the RTF translation 415 */ 416 int CountRTFSize(unsigned char *buffer) { 417 int size = 0; 418 char bold = 0, uline = 0, incolor = 0, inbg = 0, reverse = 0; 419 char *buf = buffer; 420 421 for (; *buf; buf++) 422 { 423 if (*buf == '{' || *buf == '}' || *buf == '\\') 424 size++; 425 else if (*buf == '\r') 426 { 427 if (*(buf+1) && *(buf+1) == '\n') 428 { 429 buf++; 430 if (bold) 431 size += 3; 432 if (uline) 433 size += 7; 434 if (incolor && !reverse) 435 size += 4; 436 if (inbg && !reverse) 437 size += 11; 438 if (reverse) 439 size += 15; 440 if (bold || uline || incolor || inbg || reverse) 441 size++; 442 bold = uline = incolor = inbg = reverse = 0; 443 size +=6; 444 continue; 445 } 446 } 447 else if (*buf == '\n') 448 { 449 if (bold) 450 size += 3; 451 if (uline) 452 size += 7; 453 if (incolor && !reverse) 454 size += 4; 455 if (inbg && !reverse) 456 size += 11; 457 if (reverse) 458 size += 15; 459 if (bold || uline || incolor || inbg || reverse) 460 size++; 461 bold = uline = incolor = inbg = reverse = 0; 462 size +=6; 463 continue; 464 } 465 else if (*buf == '\2') 466 { 467 if (bold) 468 size += 4; 469 else 470 size += 3; 471 bold = !bold; 472 continue; 473 } 474 else if (*buf == '\3' && reverse) 475 { 476 if (*(buf+1) && isdigit(*(buf+1))) 477 { 478 ++buf; 479 if (*(buf+1) && isdigit(*(buf+1))) 480 ++buf; 481 if (*(buf+1) && *(buf+1) == ',') 482 { 483 if (*(buf+2) && isdigit(*(buf+2))) 484 { 485 buf+=2; 486 if (*(buf+1) && isdigit(*(buf+1))) 487 ++buf; 488 } 489 } 490 } 491 continue; 492 } 493 else if (*buf == '\3' && !reverse) 494 { 495 size += 3; 496 if (*(buf+1) && !isdigit(*(buf+1))) 497 { 498 incolor = 0; 499 size++; 500 if (inbg) 501 { 502 inbg = 0; 503 size += 11; 504 } 505 } 506 else if (*(buf+1)) 507 { 508 unsigned char color[3]; 509 int number; 510 color[0] = *(++buf); 511 color[1] = 0; 512 if (*(buf+1) && isdigit(*(buf+1))) 513 color[1] = *(++buf); 514 color[2] = 0; 515 number = atoi(color); 516 if (number == 99 || number == 1) 517 size += 2; 518 else if (number == 0) 519 size++; 520 else { 521 number %= 16; 522 _itoa(number, color, 10); 523 size += strlen(color); 524 } 525 color[2] = 0; 526 number = atoi(color); 527 if (*(buf+1) && *(buf+1) == ',') 528 { 529 if (*(buf+2) && isdigit(*(buf+2))) 530 { 531 size += 10; 532 buf++; 533 color[0] = *(++buf); 534 color[1] = 0; 535 if (*(buf+1) && isdigit(*(buf+1))) 536 color[1] = *(++buf); 537 color[2] = 0; 538 number = atoi(color); 539 if (number == 1) 540 size += 2; 541 else if (number == 0 || number == 99) 542 size++; 543 else 544 { 545 number %= 16; 546 _itoa(number, color, 10); 547 size += strlen(color); 548 } 549 inbg = 1; 550 } 551 } 552 incolor = 1; 553 } 554 size++; 555 continue; 556 } 557 else if (*buf == '\17') 558 { 559 if (bold) 560 size += 3; 561 if (uline) 562 size += 7; 563 if (incolor && !reverse) 564 size += 4; 565 if (inbg && !reverse) 566 size += 11; 567 if (reverse) 568 size += 15; 569 if (bold || uline || incolor || inbg || reverse) 570 size++; 571 bold = uline = incolor = inbg = reverse = 0; 572 continue; 573 } 574 else if (*buf == '\26') 575 { 576 if (reverse) 577 size += 16; 578 else 579 size += 17; 580 reverse = !reverse; 581 continue; 582 } 583 else if (*buf == '\37') 584 { 585 if (uline) 586 size += 8; 587 else 588 size += 4; 589 uline = !uline; 590 continue; 591 } 592 size++; 593 } 594 size += strlen("{\\rtf1\\ansi\\ansicpg1252\\deff0{\\fonttbl{\\f0\\fmodern\\fprq1\\" 595 "fcharset0 Fixedsys;}}\r\n" 596 MIRC_COLORS 597 "\\viewkind4\\uc1\\pard\\lang1033\\f0\\fs20")+1; 598 return (size); 599 } 600 601 /* Converts a string containing IRC codes to RTF 602 * Parameters: 603 * buffer - The input buffer containing IRC codes 604 * string - The output buffer in RTF 605 */ 606 void IRCToRTF(unsigned char *buffer, unsigned char *string) 607 { 608 unsigned char *tmp; 609 int i = 0; 610 short bold = 0, uline = 0, incolor = 0, inbg = 0, reverse = 0; 611 sprintf(string, "{\\rtf1\\ansi\\ansicpg1252\\deff0{\\fonttbl{\\f0\\fmodern\\fprq1\\" 612 "fcharset0 Fixedsys;}}\r\n" 613 MIRC_COLORS 614 "\\viewkind4\\uc1\\pard\\lang1033\\f0\\fs20"); 615 i = strlen(string); 616 for (tmp = buffer; *tmp; tmp++) 617 { 618 if (*tmp == '{') 619 { 620 strcat(string, "\\{"); 621 i+=2; 622 continue; 623 } 624 else if (*tmp == '}') 625 { 626 strcat(string, "\\}"); 627 i+=2; 628 continue; 629 } 630 else if (*tmp == '\\') 631 { 632 strcat(string, "\\\\"); 633 i+=2; 634 continue; 635 } 636 else if (*tmp == '\r') 637 { 638 if (*(tmp+1) && *(tmp+1) == '\n') 639 { 640 tmp++; 641 if (bold) 642 { 643 strcat(string, "\\b0 "); 644 i+=3; 645 } 646 if (uline) 647 { 648 strcat(string, "\\ulnone"); 649 i+=7; 650 } 651 if (incolor && !reverse) 652 { 653 strcat(string, "\\cf0"); 654 i+=4; 655 } 656 if (inbg && !reverse) 657 { 658 strcat(string, "\\highlight0"); 659 i +=11; 660 } 661 if (reverse) { 662 strcat(string, "\\cf0\\highlight0"); 663 i += 15; 664 } 665 if (bold || uline || incolor || inbg || reverse) 666 string[i++] = ' '; 667 bold = uline = incolor = inbg = reverse = 0; 668 strcat(string, "\\par\r\n"); 669 i +=6; 670 } 671 else 672 string[i++]='\r'; 673 continue; 674 } 675 else if (*tmp == '\n') 676 { 677 if (bold) 678 { 679 strcat(string, "\\b0 "); 680 i+=3; 681 } 682 if (uline) 683 { 684 strcat(string, "\\ulnone"); 685 i+=7; 686 } 687 if (incolor && !reverse) 688 { 689 strcat(string, "\\cf0"); 690 i+=4; 691 } 692 if (inbg && !reverse) 693 { 694 strcat(string, "\\highlight0"); 695 i +=11; 696 } 697 if (reverse) { 698 strcat(string, "\\cf0\\highlight0"); 699 i += 15; 700 } 701 if (bold || uline || incolor || inbg || reverse) 702 string[i++] = ' '; 703 bold = uline = incolor = inbg = reverse = 0; 704 strcat(string, "\\par\r\n"); 705 i +=6; 706 continue; 707 } 708 else if (*tmp == '\2') 709 { 710 if (bold) 711 { 712 strcat(string, "\\b0 "); 713 i+=4; 714 } 715 else 716 { 717 strcat(string, "\\b "); 718 i+=3; 719 } 720 bold = !bold; 721 continue; 722 } 723 else if (*tmp == '\3' && reverse) 724 { 725 if (*(tmp+1) && isdigit(*(tmp+1))) 726 { 727 ++tmp; 728 if (*(tmp+1) && isdigit(*(tmp+1))) 729 ++tmp; 730 if (*(tmp+1) && *(tmp+1) == ',') 731 { 732 if (*(tmp+2) && isdigit(*(tmp+2))) 733 { 734 tmp+=2; 735 if (*(tmp+1) && isdigit(*(tmp+1))) 736 ++tmp; 737 } 738 } 739 } 740 continue; 741 } 742 else if (*tmp == '\3' && !reverse) 743 { 744 strcat(string, "\\cf"); 745 i += 3; 746 if (*(tmp+1) && !isdigit(*(tmp+1))) 747 { 748 incolor = 0; 749 string[i++] = '0'; 750 if (inbg) 751 { 752 inbg = 0; 753 strcat(string, "\\highlight0"); 754 i += 11; 755 } 756 } 757 else if (*(tmp+1)) 758 { 759 unsigned char color[3]; 760 int number; 761 color[0] = *(++tmp); 762 color[1] = 0; 763 if (*(tmp+1) && isdigit(*(tmp+1))) 764 color[1] = *(++tmp); 765 color[2] = 0; 766 number = atoi(color); 767 if (number == 99 || number == 1) 768 { 769 strcat(string, "16"); 770 i += 2; 771 } 772 else if (number == 0) 773 { 774 strcat(string, "1"); 775 i++; 776 } 777 else 778 { 779 number %= 16; 780 _itoa(number, color, 10); 781 strcat(string, color); 782 i += strlen(color); 783 } 784 if (*(tmp+1) && *(tmp+1) == ',') 785 { 786 if (*(tmp+2) && isdigit(*(tmp+2))) 787 { 788 strcat(string, "\\highlight"); 789 i += 10; 790 tmp++; 791 color[0] = *(++tmp); 792 color[1] = 0; 793 if (*(tmp+1) && isdigit(*(tmp+1))) 794 color[1] = *(++tmp); 795 color[2] = 0; 796 number = atoi(color); 797 if (number == 1) 798 { 799 strcat(string, "16"); 800 i += 2; 801 } 802 else if (number == 0 || number == 99) 803 string[i++] = '1'; 804 else 805 { 806 number %= 16; 807 _itoa(number, color, 10); 808 strcat(string,color); 809 i += strlen(color); 810 } 811 inbg = 1; 812 } 813 } 814 incolor=1; 815 } 816 string[i++] = ' '; 817 continue; 818 } 819 else if (*tmp == '\17') { 820 if (uline) { 821 strcat(string, "\\ulnone"); 822 i += 7; 823 } 824 if (bold) { 825 strcat(string, "\\b0"); 826 i += 3; 827 } 828 if (incolor && !reverse) { 829 strcat(string, "\\cf0"); 830 i += 4; 831 } 832 if (inbg && !reverse) 833 { 834 strcat(string, "\\highlight0"); 835 i += 11; 836 } 837 if (reverse) { 838 strcat(string, "\\cf0\\highlight0"); 839 i += 15; 840 } 841 if (uline || bold || incolor || inbg || reverse) 842 string[i++] = ' '; 843 uline = bold = incolor = inbg = reverse = 0; 844 continue; 845 } 846 else if (*tmp == '\26') 847 { 848 if (reverse) 849 { 850 strcat(string, "\\cf0\\highlight0 "); 851 i += 16; 852 } 853 else 854 { 855 strcat(string, "\\cf1\\highlight16 "); 856 i += 17; 857 } 858 reverse = !reverse; 859 continue; 860 } 861 862 else if (*tmp == '\37') { 863 if (uline) { 864 strcat(string, "\\ulnone "); 865 i += 8; 866 } 867 else { 868 strcat(string, "\\ul "); 869 i += 4; 870 } 871 uline = !uline; 872 continue; 873 } 874 string[i++] = *tmp; 875 } 876 strcat(string, "}"); 877 return; 878 }