comparison GUI/GUIFont.cpp @ 2502:a77c34acdbc9

Media folder
author Ritor1
date Fri, 19 Sep 2014 05:13:32 +0600
parents
children a902abdfc7f2
comparison
equal deleted inserted replaced
2501:0ff6a9e9bf7f 2502:a77c34acdbc9
1 #define _CRTDBG_MAP_ALLOC
2 #include <stdlib.h>
3 #include <crtdbg.h>
4
5 #define _CRT_SECURE_NO_WARNINGS
6 #include <string>
7 #include "Engine/ErrorHandling.h"
8
9 #include "Engine/LOD.h"
10 #include "GUIFont.h"
11 #include "GUIWindow.h"
12 #include "Engine/Graphics/Render.h"
13
14 #include "Engine/mm7_data.h"
15
16
17 extern LODFile_IconsBitmaps *pIcons_LOD;
18
19
20 struct GUIFont *pAutonoteFont;
21 struct GUIFont *pSpellFont;
22 struct GUIFont *pFontArrus;
23 struct GUIFont *pFontLucida;
24 struct GUIFont *pBook2Font;
25 struct GUIFont *pBookFont;
26 struct GUIFont *pFontCreate;
27 struct GUIFont *pFontCChar;
28 struct GUIFont *pFontComic;
29 struct GUIFont *pFontSmallnum;
30
31 char temp_string[2048];
32
33 std::array<char, 10000> pTmpBuf3;
34
35 void DrawCharToBuff(unsigned short* uXpos,unsigned char* pCharPixels, int uCharWidth, int uCharHeight, unsigned __int16* pFontPalette, __int16 draw_color, int line_width);
36
37
38 //----- (0044C448) --------------------------------------------------------
39 GUIFont *LoadFont(const char *pFontFile, const char *pFontPalette, ...)
40 {
41 int pallete_index; // eax@3
42 GUIFont *pFont;
43 unsigned int palletes_count =0;
44 va_list palettes_ptr;
45
46 pFont = (GUIFont *)pIcons_LOD->LoadRaw(pFontFile, 0);
47 va_start(palettes_ptr, pFontFile);
48
49 while (NULL!=(pFontPalette=va_arg(palettes_ptr, const char *)))
50 {
51 pallete_index =pIcons_LOD->LoadTexture(pFontPalette, TEXTURE_16BIT_PALETTE);
52 if (pallete_index == -1)
53 Error("Unable to open %s", pFontPalette);
54
55 pFont->pFontPalettes[palletes_count] = pIcons_LOD->pTextures[pallete_index].pPalette16;
56 ++palletes_count;
57 }
58 va_end(palettes_ptr);
59 pFont->palletes_count = palletes_count;
60 return pFont;
61 }
62
63 //----- (0044D2FD) --------------------------------------------------------
64 void GUIFont::_44D2FD_prolly_draw_credits_entry( GUIFont *pSecondFont, int uFrameX, int uFrameY, unsigned int w, unsigned int h,
65 unsigned __int16 firstColor, unsigned __int16 secondColor, const char *pString,
66 unsigned __int16 *pPixels, unsigned int uPixelsWidth )
67 {
68 char *work_string; // eax@1
69 unsigned __int16 *curr_pixel_pos; // esi@1
70 GUIFont *currentFont; // edi@4
71 signed int start_str_pos; // ecx@4
72 signed int line_w; // eax@6
73 GUIWindow draw_window; // [sp+Ch] [bp-5Ch]@
74 int currentColor; // [sp+74h] [bp+Ch]@4
75 int half_frameX; // [sp+80h] [bp+18h]@2
76
77 draw_window.uFrameHeight = h;
78 draw_window.uFrameW = uFrameY + h - 1;
79 draw_window.uFrameWidth = w;
80 draw_window.uFrameZ = uFrameX + w - 1;
81 ui_current_text_color = firstColor;
82 draw_window.uFrameX = uFrameX;
83 draw_window.uFrameY = uFrameY;
84
85 work_string = GUIFont::FitTwoFontStringINWindow(pString, this, pSecondFont, &draw_window, 0, 1);
86 work_string = strtok(work_string, "\n");
87 curr_pixel_pos = &pPixels[uPixelsWidth * uFrameY];
88 if ( work_string )
89 {
90 half_frameX = uFrameX >> 1;
91 while ( 1 )
92 {
93 currentFont = this;
94 ui_current_text_color = firstColor;
95 start_str_pos = 0;
96 currentColor = firstColor;
97 if ( *work_string == '_' )
98 {
99 currentFont = pSecondFont;
100 currentColor = secondColor;
101 ui_current_text_color = secondColor;
102 start_str_pos = 1;
103 }
104 line_w = (signed int)(w - currentFont->GetLineWidth(&work_string[start_str_pos]))/2;
105 if ( line_w < 0 )
106 line_w = 0;
107 currentFont->DrawTextLineToBuff(currentColor, secondColor, &curr_pixel_pos[line_w + half_frameX], work_string, uPixelsWidth);
108 curr_pixel_pos += uPixelsWidth * (currentFont->uFontHeight - 3);
109 work_string = strtok(0, "\n");
110 if ( !work_string )
111 break;
112 }
113 }
114 }
115
116 //----- (0044D1E7) --------------------------------------------------------
117 void GUIFont::DrawTextLine( unsigned int uDefaultColor, signed int uX, signed int uY,
118 const char *text, int max_len_pix )
119 {
120 signed int uX_pos; // edi@3
121 unsigned char c; // cl@4
122 unsigned __int16 draw_color; // cx@12
123 unsigned __int8 *pCharPixels; // eax@12
124 char color_code[20]; // [sp+Ch] [bp-1Ch]@16
125 int text_length; // [sp+20h] [bp-8h]@2
126 int text_color; // [sp+24h] [bp-4h]@1
127 int uCharWidth; // [sp+30h] [bp+8h]@9
128
129 if ( !text )
130 return;
131 text_color = ui_current_text_color;
132 text_length = strlen(text);
133 uX_pos=uX;
134 for (int i=0; i<text_length; ++i )
135 {
136 c = text[i];
137 if ( IsCharValid(c) )
138 {
139 switch (c)
140 {
141 case '\n': //Line Feed 0A 10:
142 return;
143 break;
144 case '\f': //Form Feed, page eject 0C 12
145 strncpy(color_code, &text[i + 1], 5);
146 color_code[5] = 0;
147 text_color = atoi(color_code);
148 ui_current_text_color = text_color;
149 i += 5;
150 break;
151 case '\t': // Horizontal tab 09
152 case '\r': //Carriage Return 0D 13
153 break;
154 default:
155 uCharWidth = pMetrics[c].uWidth;
156 if ( uCharWidth )
157 {
158 if ( i > 0 )
159 uX_pos += pMetrics[c].uLeftSpacing;
160 draw_color = text_color;
161 pCharPixels = &pFontData[font_pixels_offset[c]];
162 if ( !text_color )
163 draw_color = -1;
164 pRenderer->DrawText(uX_pos, uY, pCharPixels, uCharWidth, uFontHeight, pFontPalettes[0], draw_color, 0);
165 uX_pos += uCharWidth;
166 if ( i < text_length )
167 uX_pos += pMetrics[c].uRightSpacing;
168 }
169 }
170 }
171 }
172
173 }
174
175 //----- (0040F845) --------------------------------------------------------
176 void DrawCharToBuff( unsigned short* uXpos,unsigned char* pCharPixels, int uCharWidth, int uCharHeight,
177 unsigned __int16* pFontPalette, __int16 draw_color, int line_width )
178 {
179 unsigned __int16* draw_buff; // edi@1
180 unsigned char* pPixels; // esi@1
181 unsigned char char_pxl; // eax@3
182
183 draw_buff = uXpos;
184 pPixels = pCharPixels;
185 for(int i=0; i<uCharHeight; ++i)
186 {
187 for(int j=0; j<uCharWidth; ++j)
188 {
189 char_pxl = *pPixels++;
190 if ( char_pxl )
191 {
192 if ( char_pxl == 1 )
193 *draw_buff = pFontPalette[1];
194 else
195 *draw_buff = draw_color;
196 }
197 ++draw_buff;
198 }
199 draw_buff+=line_width-uCharWidth;
200 }
201
202 }
203
204 //----- (0044D0B5) --------------------------------------------------------
205 void GUIFont::DrawTextLineToBuff( int uColor, int a3, unsigned short* uX_buff_pos, const char *text, int line_width )
206 {
207
208 unsigned short* uX_pos; // edi@3
209 unsigned char c; // cl@4
210 unsigned __int16 draw_color; // cx@12
211 unsigned __int8 *pCharPixels; // eax@12
212 char color_code[20]; // [sp+Ch] [bp-1Ch]@16
213 int text_length; // [sp+20h] [bp-8h]@2
214 int text_color; // [sp+24h] [bp-4h]@1
215 int uCharWidth; // [sp+30h] [bp+8h]@9
216
217 if ( !text )
218 return;
219 text_color = ui_current_text_color;
220 text_length = strlen(text);
221 uX_pos=uX_buff_pos;
222 for (int i=0; i<text_length; ++i )
223 {
224 c = text[i];
225 if ( IsCharValid(c) )
226 {
227 switch (c)
228 {
229 case '\n': //Line Feed 0A 10:
230 return;
231 break;
232 case '\f': //Form Feed, page eject 0C 12
233 strncpy(color_code, &text[i + 1], 5);
234 color_code[5] = 0;
235 text_color = atoi(color_code);
236 ui_current_text_color = text_color;
237 i += 5;
238 break;
239 case '\t': // Horizontal tab 09
240 case '_':
241 break;
242 default:
243 uCharWidth = pMetrics[c].uWidth;
244 if ( uCharWidth )
245 {
246 if ( i > 0 )
247 uX_pos += pMetrics[c].uLeftSpacing;
248 draw_color = text_color;
249 pCharPixels = &pFontData[font_pixels_offset[c]];
250 if ( !text_color )
251 draw_color = -1;
252 DrawCharToBuff(uX_pos, pCharPixels, uCharWidth, uFontHeight, pFontPalettes[0], draw_color, line_width);
253 uX_pos += uCharWidth;
254 if ( i < text_length )
255 uX_pos += pMetrics[c].uRightSpacing;
256 }
257 }
258 }
259 }
260 }
261
262
263
264 //----- (0044C933) --------------------------------------------------------
265 char * GUIFont::FitTwoFontStringINWindow( const char *pString, GUIFont *pFontMain, GUIFont *pFontSecond, GUIWindow* pWindow, int startPixlOff, int a6 )
266 {
267
268 GUIFont *currentFont; // esi@3
269 unsigned char c;
270 int uInStrLen;
271 char digits[4];
272 int possible_transition_point;
273 int string_pixel_Width;
274 int start_pixel_offset;
275
276 if (!pString)
277 {
278 MessageBoxW(nullptr, L"Invalid string passed !", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Font.cpp:445", 0);
279 return 0;
280 }
281 currentFont=pFontMain; // esi@3
282 uInStrLen = strlen(pString);
283 Assert(uInStrLen < sizeof(pTmpBuf3));
284 strcpy(pTmpBuf3.data(), pString);
285 if (uInStrLen==0)
286 return pTmpBuf3.data();
287
288 start_pixel_offset=string_pixel_Width=startPixlOff;
289 possible_transition_point=0;
290 for(int i=0; i<uInStrLen; ++i)
291 {
292 c=pTmpBuf3[i];
293 if (pFontMain->IsCharValid(c))
294 {
295 switch (c)
296 {
297 case '\t': // Horizontal tab 09
298 {
299 strncpy(digits, &pTmpBuf3[i+1],3);
300 digits[3]=0;
301 string_pixel_Width = atoi(digits)+startPixlOff;
302 i+=3;
303 break;
304 }
305 case '\n': //Line Feed 0A 10
306 {
307 string_pixel_Width=start_pixel_offset;
308 possible_transition_point=i;
309 currentFont=pFontMain;
310 break;
311 }
312 case '\f': //Form Feed, page eject 0C 12
313 {
314 i+=5;
315 break;
316 }
317 case '\r': //Carriage Return 0D 13
318 {
319 if (!a6)
320 return (char*)pString;
321 break;
322 }
323 case ' ' :
324 {
325 string_pixel_Width+=currentFont->pMetrics[c].uWidth;
326 possible_transition_point=i;
327 break;
328 }
329 case '_' :
330 currentFont=pFontSecond;
331 break;
332 default:
333
334 if ((string_pixel_Width+currentFont->pMetrics[c].uWidth+ currentFont->pMetrics[c].uLeftSpacing+
335 currentFont->pMetrics[c].uRightSpacing)<pWindow->uFrameWidth)
336 {
337 if(i>possible_transition_point)
338 string_pixel_Width+=currentFont->pMetrics[c].uLeftSpacing;
339 string_pixel_Width+=currentFont->pMetrics[c].uWidth;
340 if (i<uInStrLen)
341 string_pixel_Width+=currentFont->pMetrics[c].uRightSpacing;
342 }
343 else
344 {
345 pTmpBuf3[possible_transition_point]='\n';
346
347 if ( currentFont== pFontSecond)
348 {
349
350 for(int k=uInStrLen-1; k>=possible_transition_point+1; --k)
351 pTmpBuf3[k] = pTmpBuf3[k-1];
352
353 ++uInStrLen;
354 ++possible_transition_point;
355 pTmpBuf3[possible_transition_point] = '_';
356
357 }
358 string_pixel_Width=start_pixel_offset;
359
360 for(int j=possible_transition_point;j<i; ++j )
361 {
362 c=pTmpBuf3[j];
363 if (pFontMain->IsCharValid(c))
364 {
365 if(j>possible_transition_point)
366 string_pixel_Width+=pFontMain->pMetrics[c].uLeftSpacing;
367 string_pixel_Width+=pFontMain->pMetrics[c].uWidth;
368 if (j<i)
369 string_pixel_Width+=pFontMain->pMetrics[c].uRightSpacing;
370
371 }
372 }
373 }
374 }
375 }
376 }
377 return pTmpBuf3.data();
378
379 }
380
381
382 //----- (0044C6C2) --------------------------------------------------------
383 char* GUIFont::GetPageTop( const char *pInString, GUIWindow *pWindow, unsigned int uX, int a5 )
384 {
385 int text_height; // edi@1
386 char *text_str; // ebx@3
387 unsigned char c; // cl@4
388 int text_length;
389
390 text_height = 0;
391
392 if ( !pInString )
393 return 0;
394 text_str = FitTextInAWindow(pInString, this, pWindow, uX, 0);
395 text_length = strlen(text_str);
396 for ( int i = 0; i < text_length; ++i )
397 {
398 c = text_str[i];
399 if ( IsCharValid(c) )
400 {
401 switch (c)
402 {
403 case '\n': //Line Feed 0A 10:
404 text_height = text_height + (uFontHeight - 3);
405 if ( text_height >= (signed int)(a5 * (pWindow->uFrameHeight - (uFontHeight - 3))) )
406 return &text_str[i];
407 break;
408 case '\f': //Form Feed, page eject 0C 12
409 i += 5;
410 break;
411 case '\t': // Horizontal tab 09
412 case '\r': //Carriage Return 0D 13
413 i += 3;
414 break;
415 }
416 if ( text_height >= (signed int)(a5 * pWindow->uFrameHeight) )
417 break;
418 }
419 }
420 return &text_str[0];
421 }
422
423 //----- (0044C62E) --------------------------------------------------------
424 int GUIFont::GetStringHeight2( GUIFont *secondFont, const char *text_str, GUIWindow* pWindow, int startX, int a6 )
425 {
426
427 int uAllHeght;
428 int uStringLen;
429 unsigned char c;
430 char *test_string;
431
432 if ( !text_str )
433 return 0;
434 uAllHeght = uFontHeight - 3;
435 test_string = FitTwoFontStringINWindow(text_str, this, secondFont, pWindow, startX, 0);
436 uStringLen = strlen(test_string);
437 for (int i = 0; i < uStringLen; ++i)
438 {
439 c = test_string[i];
440 if (IsCharValid(c))
441 {
442 switch (c)
443 {
444 case '\n': //Line Feed 0A 10:
445 uAllHeght+= uFontHeight - 3;
446 break;
447 case '\f': //Form Feed, page eject 0C 12
448 i += 5;
449 break;
450 case '\t': // Horizontal tab 09
451 case '\r': //Carriage Return 0D 13
452 if (a6 != 1)
453 i += 3;
454 break;
455 }
456 }
457 }
458
459 return uAllHeght;
460 }
461
462 //----- (0044C59D) --------------------------------------------------------
463 int GUIFont::CalcTextHeight( const char *pString, struct GUIWindow *pWindow, int uXOffset, int a5 )
464 {
465 int uAllHeght;
466 int uStringLen;
467 unsigned char c;
468 char *test_string;
469
470 if (!pString)
471 return 0;
472 uAllHeght = uFontHeight - 6;
473 test_string = FitTextInAWindow(pString, this, pWindow, uXOffset, 0);
474 uStringLen = strlen(pString);
475 for (int i = 0; i < uStringLen; ++i)
476 {
477 c = test_string[i];
478 if (IsCharValid(c))
479 {
480 switch (c)
481 {
482 case '\n': //Line Feed 0A 10:
483 uAllHeght += uFontHeight - 3;
484 break;
485 case '\f': //Form Feed, page eject 0C 12
486 i += 5;
487 break;
488 case '\t': // Horizontal tab 09
489 case '\r': //Carriage Return 0D 13
490 if (a5 != 1)
491 i += 3;
492 break;
493 }
494 }
495 }
496 return uAllHeght;
497 }
498
499 //----- (0044C51E) --------------------------------------------------------
500 int GUIFont::GetLineWidth(const char *pString)
501 {
502 int str_len; // ebp@3
503 int string_line_width; // esi@3
504 unsigned char c;
505
506 if (!pString)
507 return 0;
508 str_len = strlen(pString);
509 string_line_width = 0;
510 for ( int i = 0; i < str_len; ++i )
511 {
512 c = pString[i];
513 if (IsCharValid(c))
514 {
515 switch (c)
516 {
517 case '\t':
518 case '\n':
519 case '\r':
520 return string_line_width;
521 case '\f':
522 i += 5;
523 break;
524 default:
525 if (i > 0)
526 string_line_width += pMetrics[c].uLeftSpacing;
527 string_line_width += pMetrics[c].uWidth;
528 if (i < str_len)
529 string_line_width +=pMetrics[c].uRightSpacing;
530 }
531 }
532 }
533 return string_line_width;
534 }
535
536
537 //----- (0044C502) --------------------------------------------------------
538 int GUIFont::AlignText_Center(unsigned int uCenterX, const char *pString)
539 {
540 signed int position; // esi@1
541
542 position = (signed int)(uCenterX - GetLineWidth(pString)) >> 1;
543 if ( position >= 0 )
544 return position;
545 else
546 return 0;
547 }
548
549 //----- (0044C768) --------------------------------------------------------
550 char * FitTextInAWindow( const char *pInString, GUIFont *pFont, GUIWindow *pWindow, signed int uX, int a5 )
551 {
552 unsigned char c;
553 int uInStrLen;
554 char digits[4];
555 int possible_transition_point;
556 int string_pixel_Width;
557 int start_pixel_offset;
558
559 if (!pInString)
560 {
561 MessageBoxW(nullptr, L"Invalid string passed !", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Font.cpp:445", 0);
562 return 0;
563 }
564 uInStrLen = strlen(pInString);
565 strcpy(&temp_string[0], pInString);
566 if (uInStrLen == 0)
567 return &temp_string[0];
568
569 start_pixel_offset = string_pixel_Width=uX;
570 possible_transition_point = 0;
571 for ( int i = 0; i < uInStrLen; ++i )
572 {
573 c = temp_string[i];
574 if (pFont->IsCharValid(c))
575 {
576 switch (c)
577 {
578 case '\t': // Horizontal tab 09
579 {
580 strncpy(digits, &temp_string[i + 1],3);
581 digits[3] = 0;
582 string_pixel_Width = atoi(digits)+uX;
583 i += 3;
584 break;
585 }
586 case '\n': //Line Feed 0A 10 (конец строки)
587 {
588 string_pixel_Width = start_pixel_offset;
589 possible_transition_point = i;
590 break;
591 }
592 case '\f': //Form Feed, page eject 0C 12
593 {
594 i += 5;
595 break;
596 }
597 case '\r': //Carriage Return 0D 13
598 {
599 if ( !a5 )
600 return (char*)pInString;
601 break;
602 }
603 case ' '://пробел
604 {
605 string_pixel_Width += pFont->pMetrics[c].uWidth;
606 possible_transition_point = i;
607 break;
608 }
609 default:
610 if ((string_pixel_Width + pFont->pMetrics[c].uWidth + pFont->pMetrics[c].uLeftSpacing +
611 pFont->pMetrics[c].uRightSpacing) < pWindow->uFrameWidth )//наращивание длины строки или перенос
612 {
613 if ( i > possible_transition_point )
614 string_pixel_Width += pFont->pMetrics[c].uLeftSpacing;
615 string_pixel_Width += pFont->pMetrics[c].uWidth;
616 if (i < uInStrLen)
617 string_pixel_Width += pFont->pMetrics[c].uRightSpacing;
618 }
619 else//перенос строки и слова
620 {
621 temp_string[possible_transition_point] ='\n';
622 string_pixel_Width = start_pixel_offset;
623 if ( i > possible_transition_point )
624 {
625 for ( int j = possible_transition_point; j < i; ++j )
626 {
627 c = temp_string[j];
628 if (pFont->IsCharValid(c))
629 {
630 if ( j > possible_transition_point )
631 string_pixel_Width += pFont->pMetrics[c].uLeftSpacing;
632 string_pixel_Width += pFont->pMetrics[c].uWidth;
633 if ( j < i )
634 string_pixel_Width += pFont->pMetrics[c].uRightSpacing;
635 }
636 }
637 }
638 }
639 }
640 }
641 }
642 return &temp_string[0];
643 }
644 //----- (00414162) --------------------------------------------------------
645 void uGameUIFontMain_initialize()
646 {
647 uGameUIFontMain = Color16(0xAu, 0, 0);
648 }
649
650 //----- (00414174) --------------------------------------------------------
651 void uGameUIFontShadow_initialize()
652 {
653 uGameUIFontShadow = Color16(0xE6u, 214, 193);
654 }