DIALOG.CPP (35159B)
1 // 2 // Copyright 2020 Electronic Arts Inc. 3 // 4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 5 // software: you can redistribute it and/or modify it under the terms of 6 // the GNU General Public License as published by the Free Software Foundation, 7 // either version 3 of the License, or (at your option) any later version. 8 9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 10 // in the hope that it will be useful, but with permitted additional restrictions 11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 // distributed with this program. You should have received a copy of the 13 // GNU General Public License along with permitted additional restrictions 14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection 15 16 /* $Header: F:\projects\c&c\vcs\code\dialog.cpv 2.17 16 Oct 1995 16:51:50 JOE_BOSTIC $ */ 17 /*********************************************************************************************** 18 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** 19 *********************************************************************************************** 20 * * 21 * Project Name : Command & Conquer * 22 * * 23 * File Name : DIALOG.CPP * 24 * * 25 * Programmer : Joe L. Bostic * 26 * * 27 * Start Date : September 10, 1993 * 28 * * 29 * Last Update : May 18, 1995 [JLB] * 30 * * 31 *---------------------------------------------------------------------------------------------* 32 * Functions: * 33 * Clip_Text_Print -- Prints text with clipping and <TAB> support. * 34 * Dialog_Box -- draws a dialog background box * 35 * Display_Place_Building -- Displays the "place building" dialog box. * 36 * Display_Select_Target -- Displays the "choose target" prompt. * 37 * Display_Status -- Display the player scenario status box. * 38 * Draw_Box -- Displays a highlighted box. * 39 * Fancy_Text_Print -- Prints text with a drop shadow. * 40 * Redraw_Needed -- Determine if sidebar needs to be redrawn. * 41 * Render_Bar_Graph -- Renders a specified bargraph. * 42 * Simple_Text_Print -- Prints text with a drop shadow. * 43 * Window_Box -- Draws a fancy box over the specified window. * 44 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 45 46 #include "function.h" 47 48 49 /*********************************************************************************************** 50 * Dialog_Box -- draws a dialog background box * 51 * * 52 * INPUT: * 53 * x,y,w,h the usual * 54 * * 55 * OUTPUT: * 56 * none. * 57 * * 58 * WARNINGS: * 59 * none. * 60 * * 61 * HISTORY: * 62 * 01/26/1995 BR : Created. * 63 *=============================================================================================*/ 64 void Dialog_Box(int x, int y, int w, int h) 65 { 66 Draw_Box( x, y, w, h, BOXSTYLE_GREEN_BORDER, true); 67 } 68 69 70 /*********************************************************************************************** 71 * Draw_Box -- Displays a highlighted box. * 72 * * 73 * This will draw a highlighted box to the logicpage. It can * 74 * optionally fill the box with a color as well. This is a low level * 75 * function and thus, it doesn't do any graphic mode color adjustments. * 76 * * 77 * INPUT: x,y -- Upper left corner of the box to be drawn (pixels). * 78 * * 79 * w,h -- Width and height of box (in pixels). * 80 * * 81 * up -- Is the box rendered in the "up" stated? * 82 * * 83 * filled-- Is the box to be filled. * 84 * * 85 * OUTPUT: none * 86 * * 87 * WARNINGS: none * 88 * * 89 * HISTORY: * 90 * 05/28/1991 JLB : Created. * 91 * 05/30/1992 JLB : Embedded color codes. * 92 * 07/31/1992 JLB : Depressed option added. * 93 *=============================================================================================*/ 94 extern void CC_Texture_Fill (void const *shapefile, int shapenum, int xpos, int ypos, int width, int height); 95 96 void Draw_Box(int x, int y, int w, int h, BoxStyleEnum up, bool filled) 97 { 98 static BoxStyleType const ButtonColors[BOXSTYLE_COUNT] = { 99 100 //Filler, Shadow, Hilite, Corner colors 101 102 { LTGREY, WHITE, DKGREY, LTGREY}, // 0 Button is down. 103 { LTGREY, DKGREY, WHITE, LTGREY}, // 1 Button is up w/border. 104 { LTBLUE, BLUE, LTCYAN, LTBLUE}, // 2 Raised blue. 105 { DKGREY, WHITE, BLACK, DKGREY}, // 3 Button is disabled down. 106 { DKGREY, BLACK, WHITE, LTGREY}, // 4 Button is disabled up. 107 { LTGREY, DKGREY, WHITE, LTGREY}, // 5 Button is up w/arrows. 108 //{ CC_GREEN_BKGD, CC_LIGHT_GREEN, CC_GREEN_SHADOW, CC_GREEN_CORNERS }, // 6 Button is down. 109 //{ CC_GREEN_BKGD, CC_GREEN_SHADOW, CC_LIGHT_GREEN, CC_GREEN_CORNERS }, // 7 Button is up w/border. 110 { CC_GREEN_BKGD, 14, 12, 13 }, // 6 Button is down. 111 { CC_GREEN_BKGD, 12, 14, 13 }, // 7 Button is up w/border. 112 { DKGREY, WHITE, BLACK, DKGREY}, // 8 Button is disabled down. 113 { DKGREY, BLACK, LTGREY, DKGREY}, // 9 Button is disabled up. 114 //{ BLACK, CC_GREEN_BOX, CC_GREEN_BOX, BLACK}, // 10 List box. 115 //{ BLACK, CC_GREEN_BOX, CC_GREEN_BOX, BLACK}, // 11 Menu box. 116 { BLACK, 14, 14, BLACK}, // 10 List box. 117 { BLACK, 14, 14, BLACK}, // 11 Menu box. 118 }; 119 120 w--; 121 h--; 122 BoxStyleType const &style = ButtonColors[up]; 123 124 if (filled) { 125 if (style.Filler == CC_GREEN_BKGD){ 126 CC_Texture_Fill (MixFileClass::Retrieve("BTEXTURE.SHP"), InMainLoop, x, y, w, h); 127 }else{ 128 LogicPage->Fill_Rect( x, y, x+w, y+h, style.Filler); 129 } 130 } 131 132 switch ( up ) { 133 case ( BOXSTYLE_GREEN_BOX ): 134 LogicPage->Draw_Rect(x, y, x+w, y+h, style.Highlight); 135 break; 136 137 case ( BOXSTYLE_GREEN_BORDER ): 138 LogicPage->Draw_Rect(x+1, y+1, x+w-1, y+h-1, style.Highlight); 139 break; 140 141 default: 142 LogicPage->Draw_Line(x, y+h, x+w, y+h, style.Shadow); 143 LogicPage->Draw_Line(x+w, y, x+w, y+h, style.Shadow); 144 145 LogicPage->Draw_Line(x, y, x+w, y, style.Highlight); 146 LogicPage->Draw_Line(x, y, x, y+h, style.Highlight); 147 148 LogicPage->Put_Pixel(x, y+h, style.Corner); 149 LogicPage->Put_Pixel(x+w, y, style.Corner); 150 break; 151 } 152 } 153 154 155 /*********************************************************************************************** 156 * Format_Window_String -- Separates a String into Lines. * 157 * This function will take a long string and break it up into lines * 158 * which are not longer then the window width. Any character < ' ' is * 159 * considered a new line marker and will be replaced by a NULL. * 160 * * 161 * INPUT: char *String - string to be formated. * 162 * int maxlinelen - Max length of any line in pixels. * 163 * * 164 * OUTPUT: int - number of lines string is. * 165 * * 166 * WARNINGS: The string passed in will be modified - NULLs will be put * 167 * into each position that will be a new line. * 168 * * 169 * HISTORY: * 170 * 03/27/1992 SB : Created. * 171 * 05/18/1995 JLB : Greatly revised for new font system. * 172 *=============================================================================================*/ 173 int Format_Window_String(char * string, int maxlinelen, int & width, int & height) 174 { 175 int linelen; 176 int lines = 0; 177 width = 0; 178 height = 0; 179 180 // In no string was passed in, then there are no lines. 181 if (!string) return(0); 182 183 // While there are more letters left divide the line up. 184 while (*string) { 185 linelen = 0; 186 height += FontHeight + FontYSpacing; 187 lines++; 188 189 // While the current line is less then the max length... 190 while (linelen < maxlinelen && *string != '\r' && *string != '\0') { 191 linelen += Char_Pixel_Width(*string++); 192 } 193 194 // if the line is to long... 195 if (linelen >= maxlinelen) { 196 197 /* 198 ** Back up to an appropriate location to break. 199 */ 200 while (*string != ' ' && *string != '\r' && *string != '\0') { 201 linelen -= Char_Pixel_Width(*string--); 202 } 203 204 } 205 206 /* 207 ** Record the largest width of the worst case string. 208 */ 209 if (linelen > width) { 210 width = linelen; 211 } 212 213 /* 214 ** Force a break at the end of the line. 215 */ 216 if (*string) { 217 *string++ = '\r'; 218 } 219 } 220 return(lines); 221 } 222 223 224 /*********************************************************************************************** 225 * Window_Box -- Draws a fancy box over the specified window. * 226 * * 227 * This routine will draw a fancy (shaded) box over the specified * 228 * window. This is the effect used to give the polished look to * 229 * screen rectangles without having to use art. * 230 * * 231 * INPUT: window -- Specified window to fill and border. * 232 * * 233 * style -- The style to render the window. * 234 * * 235 * OUTPUT: none * 236 * * 237 * WARNINGS: The rendering is done to the LogicPage. * 238 * * 239 * HISTORY: * 240 * 03/03/1992 JLB : Created. * 241 * 07/31/1992 JLB : Cool raised border effect. * 242 * 06/08/1994 JLB : Takes appropriate enumeration parameters. * 243 *=============================================================================================*/ 244 void Window_Box(WindowNumberType window, BoxStyleEnum style) 245 { 246 int x,y,w,h; // Window dimensions. 247 int border; // Width of border. 248 249 static int _border[BOXSTYLE_COUNT][2] = { 250 {0,0}, // 0 Simple beveled edge. 251 {2,4}, // 1 Wide raised border. 252 {1,1}, // 2 Thick beveled edge. 253 {2,1}, // 3 Thin raised border. 254 {0,0}, // 4 Simple beveled edge. 255 {20,0}, // 5 Simple beveled edge. 256 {0,0}, // 6 Simple beveled edge. 257 {2,4}, // 7 Wide raised border. 258 {0,0}, // 8 Simple beveled edge. 259 {20,0}, // 9 Simple beveled edge. 260 {0,1} // 10 Simple 1 pixel box. 261 }; 262 263 x = WindowList[window][WINDOWX]<<3; 264 y = WindowList[window][WINDOWY]; 265 w = WindowList[window][WINDOWWIDTH]<<3; 266 h = WindowList[window][WINDOWHEIGHT]; 267 268 /* 269 ** If it is to be rendered to the seenpage, then 270 ** hide the mouse. 271 */ 272 if (LogicPage == (&SeenBuff)) Conditional_Hide_Mouse(x,y,x+w,y+h); 273 274 Draw_Box(x, y, w, h, style, true); 275 border = _border[style][1]; 276 277 /* 278 ** Draw the second border if requested. 279 */ 280 if (border) { 281 Draw_Box(x+border, y+border, w-(border<<1), h-(border<<1), style, false); 282 } 283 284 /* 285 ** Restore the mouse if it has been hidden and return. 286 */ 287 if (LogicPage == &SeenBuff) Conditional_Show_Mouse(); 288 } 289 290 291 /*********************************************************************************************** 292 * Simple_Text_Print -- Prints text with a drop shadow. * 293 * * 294 * This routine functions like Text_Print, but will render a drop * 295 * shadow (in black). * 296 * * 297 * INPUT: text -- Pointer to text to render. * 298 * * 299 * x,y -- Pixel coordinate for to print text. * 300 * * 301 * fore -- Foreground color. * 302 * * 303 * back -- Background color. * 304 * * 305 * flag -- Text print control flags. * 306 * * 307 * OUTPUT: none * 308 * * 309 * WARNINGS: none * 310 * * 311 * HISTORY: * 312 * 12/24/1991 JLB : Created. * 313 * 10/26/94 JLB : Handles font X spacing in a more friendly manner. * 314 *=============================================================================================*/ 315 void Simple_Text_Print(char const *text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag) 316 { 317 static int yspace=0; // Y spacing adjustment for font. 318 static int xspace=0; // Spacing adjustment for font. 319 void const * font=0; // Font to use. 320 321 ////////////////#if (0) 322 static unsigned char _textfontpal[16][16] = { 323 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 324 { 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 26, 25, 24 }, 325 { 0,135, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 136,135,119, 2 }, 326 { 0,159, 0, 0, 0, 0, 0, 0, 0, 0, 0,142, 143,159,41 ,167 }, 327 328 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 329 { 0,157, 0, 0, 0, 0, 0, 0, 0, 0, 0,180, 180,157,158, 5 }, 330 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 331 { 0,179, 0, 0, 0, 0, 0, 0, 0, 0, 0,180, 180,179,178,176 }, 332 333 { 0,123, 0, 0, 0, 0, 0, 0, 0, 0, 0,122, 122,123,125,127 }, 334 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 335 { 0,203, 0, 0, 0, 0, 0, 0, 0, 0, 0,204, 204,203,202,201 }, 336 { 0, 1, 4,166, 41, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 337 338 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 339 340 { 0,203, 0, 0, 0, 0, 0, 0, 0, 0, 0,204, 204,203,202,201 }, 341 { 0,203, 0, 0, 0, 0, 0, 0, 0, 0, 0,204, 204,203,202,201 }, 342 343 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 344 }; 345 static unsigned char _textpalmedium[16] = { 346 0, 25, 119,41, 0, 158,0, 178, 125,0, 202,0, 0, 0, 0, 0 347 }; 348 349 static unsigned char _textpalbright[16] = { 350 0, 24, 2, 4, 0, 5, 0, 176, 127,0, 201,0, 0, 0, 0, 0 351 }; 352 ///////////////////////#endif //(0) 353 354 int point; // Requested font size. 355 int shadow; // Requested shadow value. 356 unsigned char fontpalette[16]; // Working font palette array. 357 memset(&fontpalette[0], back, 16); 358 359 if ((flag & 0xf) == TPF_VCR) { 360 fontpalette[3] = 12; 361 fontpalette[9] = 15; 362 fontpalette[10] = 200; 363 fontpalette[11] = 201; 364 fontpalette[12] = 202; 365 fontpalette[13] = 203; 366 fontpalette[14] = 204; 367 fontpalette[15] = 205; 368 } 369 370 char *tempstr = NULL; 371 372 if (text){ 373 /* 374 ** remove any 0xff characters from the string 375 */ 376 tempstr = new char [strlen (text)+1]; 377 char *tempptr = tempstr; 378 379 for ( int i=0 ; i<(int)strlen(text)+1 ; i++ ) { 380 if (text[i] != -1){ 381 *tempptr = text[i]; 382 tempptr++; 383 } 384 } 385 } 386 387 /* 388 ** A gradient font always requires special fixups for the palette. 389 */ 390 if ((flag & 0xf) == TPF_6PT_GRAD || 391 (flag & 0xf) == TPF_GREEN12_GRAD || 392 (flag & 0xf) == TPF_GREEN12) { 393 /* 394 ** If a gradient palette was requested, then fill in the font palette array 395 ** according to the color index specified. 396 */ 397 if (flag & TPF_USE_GRAD_PAL) { 398 memcpy(&fontpalette[0], _textfontpal[ (fore & 0x0f) ], 16); 399 } else { 400 401 /* 402 ** Special adjustment for fonts that have gradient artwork. When there is 403 ** no special gradient effect desired, then set the font color based on the 404 ** forground color specified. 405 */ 406 memset(&fontpalette[4], fore, 12); 407 } 408 409 if (flag & TPF_MEDIUM_COLOR) { 410 fore = _textpalmedium[fore & 0x0F]; 411 memset(&fontpalette[4], fore, 12); 412 }else{ 413 if (flag & TPF_BRIGHT_COLOR) { 414 fore = _textpalbright[fore & 0x0F]; 415 memset(&fontpalette[4], fore, 12); 416 }else{ 417 fore = fontpalette[1]; 418 } 419 } 420 } 421 422 423 /* 424 ** Change the current font if it differs from the font desired. 425 */ 426 point = (flag & (TextPrintType)0x000F); 427 xspace = 1; 428 yspace = 0; 429 430 switch (point) { 431 case TPF_GREEN12: 432 font = Green12FontPtr; 433 break; 434 435 case TPF_GREEN12_GRAD: 436 font = Green12GradFontPtr; 437 break; 438 439 case TPF_MAP: 440 font = MapFontPtr; 441 xspace -= 1; 442 break; 443 444 case TPF_VCR: 445 font = VCRFontPtr; 446 break; 447 448 case TPF_6PT_GRAD: 449 font = GradFont6Ptr; 450 xspace -= 1; 451 //yspace -= 1; 452 break; 453 454 case TPF_3POINT: 455 xspace += 1; 456 font = Font3Ptr; 457 flag = flag & ~(TPF_DROPSHADOW|TPF_FULLSHADOW|TPF_NOSHADOW); 458 break; 459 460 case TPF_6POINT: 461 font = Font6Ptr; 462 xspace -= 1; 463 //yspace -= 1; 464 break; 465 466 case TPF_8POINT: 467 font = Font8Ptr; 468 xspace -= 2; 469 yspace -= 4; 470 break; 471 472 case TPF_LED: 473 xspace -= 4; 474 font = FontLEDPtr; 475 break; 476 477 default: 478 font = FontPtr; 479 break; 480 } 481 482 /* 483 ** Change the current font palette according to the dropshadow flags. 484 */ 485 shadow = (flag & (TPF_NOSHADOW|TPF_DROPSHADOW|TPF_FULLSHADOW|TPF_LIGHTSHADOW)); 486 switch (shadow) { 487 488 /* 489 ** The text is rendered plain. 490 */ 491 case TPF_NOSHADOW: 492 fontpalette[2] = back; 493 fontpalette[3] = back; 494 xspace -= 1; 495 yspace -= 2; 496 break; 497 498 /* 499 ** The text is rendered with a simple 500 ** drop shadow. 501 */ 502 case TPF_DROPSHADOW: 503 fontpalette[2] = BLACK; 504 fontpalette[3] = back; 505 xspace -= 1; 506 break; 507 508 /* 509 ** Special engraved text look for the options 510 ** dialog system. 511 */ 512 case TPF_LIGHTSHADOW: 513 fontpalette[2] = ((14 * 16) + 7)+1; 514 fontpalette[3] = back; 515 xspace -= 1; 516 break; 517 518 /* 519 ** Each letter is surrounded by black. This is used 520 ** when the text will be over a non-plain background. 521 */ 522 case TPF_FULLSHADOW: 523 fontpalette[2] = BLACK; 524 fontpalette[3] = BLACK; 525 xspace -= 1; 526 break; 527 528 default: 529 break; 530 } 531 fontpalette[0] = back; 532 fontpalette[1] = fore; 533 534 /* 535 ** Set the font and spacing according to the values they should be. 536 */ 537 FontXSpacing = xspace; 538 FontYSpacing = yspace; 539 Set_Font(font); 540 Set_Font_Palette(fontpalette); 541 542 /* 543 ** Display the (centered) message if there is one. 544 */ 545 if (text && *text) { 546 switch (flag & (TPF_CENTER|TPF_RIGHT)) { 547 case TPF_CENTER: 548 x -= String_Pixel_Width(tempstr)>>1; 549 break; 550 551 case TPF_RIGHT: 552 x -= String_Pixel_Width(tempstr); 553 break; 554 555 default: 556 break; 557 } 558 559 if (x < (unsigned)SeenBuff.Get_Width() && y < (unsigned)SeenBuff.Get_Height()) { 560 LogicPage->Print(tempstr, x, y, fore, back); 561 } 562 } 563 if (tempstr){ 564 delete [] tempstr; 565 } 566 567 } 568 569 570 /*********************************************************************************************** 571 * Fancy_Text_Print -- Prints text with a drop shadow. * 572 * * 573 * This routine functions like Text_Print, but will render a drop * 574 * shadow (in black). * 575 * * 576 * INPUT: text -- Text number to print. * 577 * * 578 * x,y -- Pixel coordinate for to print text. * 579 * * 580 * fore -- Foreground color. * 581 * * 582 * back -- Background color. * 583 * * 584 * flag -- Text print control flags. * 585 * * 586 * OUTPUT: none * 587 * * 588 * WARNINGS: This routine is much slower than normal text print and * 589 * if rendered to the SEENPAGE, the intermediate rendering * 590 * steps could be visible. * 591 * * 592 * HISTORY: * 593 * 11/29/1994 JLB : Created * 594 *=============================================================================================*/ 595 void Fancy_Text_Print(int text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, ...) 596 { 597 char buffer[512]; // Working staging buffer. 598 va_list arg; // Argument list var. 599 600 /* 601 ** If the text number is valid, then process it. 602 */ 603 if (text != TXT_NONE) { 604 va_start(arg, flag); 605 606 /* 607 ** The text string must be locked since the vsprintf function doesn't know 608 ** how to handle EMS pointers. 609 */ 610 char const * tptr = Text_String(text); 611 vsprintf(buffer, tptr, arg); 612 va_end(arg); 613 614 Simple_Text_Print(buffer, x, y, fore, back, flag); 615 } else { 616 617 /* 618 ** Just the flags are to be changed, since the text number is TXT_NONE. 619 */ 620 Simple_Text_Print((char const *)0, x, y, fore, back, flag); 621 } 622 } 623 624 625 /*********************************************************************************************** 626 * Fancy_Text_Print -- Prints text with a drop shadow. * 627 * * 628 * This routine functions like Text_Print, but will render a drop * 629 * shadow (in black). * 630 * * 631 * INPUT: text -- Pointer to text to render. * 632 * * 633 * x,y -- Pixel coordinate for to print text. * 634 * * 635 * fore -- Foreground color. * 636 * * 637 * back -- Background color. * 638 * * 639 * flag -- Text print control flags. * 640 * * 641 * OUTPUT: none * 642 * * 643 * WARNINGS: This routine is much slower than normal text print and * 644 * if rendered to the SEENPAGE, the intermediate rendering * 645 * steps could be visible. * 646 * * 647 * HISTORY: * 648 * 12/24/1991 JLB : Created. * 649 * 10/26/94 JLB : Handles font X spacing in a more friendly manner. * 650 * 11/29/1994 JLB : Separated actual draw action. * 651 *=============================================================================================*/ 652 void Fancy_Text_Print(char const *text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, ...) 653 { 654 char buffer[512]; // Working staging buffer. 655 va_list arg; // Argument list var. 656 657 /* 658 ** If there is a valid text string pointer then build the final string into the 659 ** working buffer before sending it to the simple string printing routine. 660 */ 661 if (text) { 662 663 /* 664 ** Since vsprintf doesn't know about EMS pointers, be sure to surround this 665 ** call with locking code. 666 */ 667 va_start(arg, flag); 668 vsprintf(buffer, text, arg); 669 va_end(arg); 670 671 Simple_Text_Print(buffer, x, y, fore, back, flag); 672 } else { 673 674 /* 675 ** Just the flags are desired to be changed, so call the simple print routine with 676 ** a NULL text pointer. 677 */ 678 Simple_Text_Print((char const *)0, x, y, fore, back, flag); 679 } 680 } 681 682 683 /*********************************************************************************************** 684 * Clip_Text_Print -- Prints text with clipping and <TAB> support. * 685 * * 686 * Use this routine to print text that that should be clipped at an arbitrary right margin * 687 * as well as possibly recognizing <TAB> characters. Typical users of this routine would * 688 * be list boxes. * 689 * * 690 * INPUT: text -- Reference to the text to print. * 691 * * 692 * x,y -- Pixel coordinate of the upper left corner of the text position. * 693 * * 694 * fore -- The foreground color to use. * 695 * * 696 * back -- The background color to use. * 697 * * 698 * flag -- The text print flags to use. * 699 * * 700 * width -- The maximum pixel width to draw the text. Extra characters beyond this * 701 * point will not be printed. * 702 * * 703 * tabs -- Optional pointer to a series of pixel tabstop positions. * 704 * * 705 * OUTPUT: none * 706 * * 707 * WARNINGS: none * 708 * * 709 * HISTORY: * 710 * 01/21/1995 JLB : Created. * 711 *=============================================================================================*/ 712 void Conquer_Clip_Text_Print(char const *text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, unsigned width, int const * tabs) 713 { 714 char buffer[512]; 715 716 if (text) { 717 strcpy(buffer, text); 718 719 /* 720 ** Set the font and spacing characteristics according to the flag 721 ** value passed in. 722 */ 723 Simple_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, flag); 724 725 char * source = &buffer[0]; 726 unsigned offset = 0; 727 int processing = true; 728 while (processing && offset < width) { 729 char * ptr = strchr(source, '\t'); 730 731 /* 732 ** Zap the tab character. It will be processed later. 733 */ 734 if (ptr) { 735 *ptr = '\0'; 736 } 737 738 if (*source) { 739 740 /* 741 ** Scan forward until the end of the string is reached or the 742 ** maximum width, whichever comes first. 743 */ 744 int w = 0; 745 char * bptr = source; 746 do { 747 w += Char_Pixel_Width(*bptr++); 748 } while(*bptr && offset+w < width); 749 750 /* 751 ** If the maximum width has been exceeded, then remove the last 752 ** character and signal that further processing is not necessary. 753 */ 754 if (offset+w >= width) { 755 bptr--; 756 w -= Char_Pixel_Width(*bptr); 757 *bptr = '\0'; 758 processing = 0; 759 } 760 761 /* 762 ** Print this text block and advance the offset accordingly. 763 */ 764 Simple_Text_Print(source, x+offset, y, fore, back, flag); 765 offset += w; 766 } 767 768 /* 769 ** If a <TAB> was the terminator for this text block, then advance 770 ** to the next tabstop. 771 */ 772 if (ptr) { 773 if (tabs) { 774 while (offset > (unsigned) *tabs) { 775 tabs++; 776 } 777 offset = (unsigned) *tabs; 778 } else { 779 offset = ((offset+1 / 50) + 1) * 50; 780 } 781 source = ptr+1; 782 } else { 783 break; 784 } 785 } 786 } 787 }