1 
2 
3 #include "studiox_includes.h"
4 #include "system_pngs.h"
5 
6 extern "C"{
7 #include "gx_utility.h"
8 #include "gx_api.h"
9 extern GX_FONT _gx_system_font_8bpp;
10 extern GX_FONT _gx_system_font_4bpp;
11 extern GX_FONT _gx_system_font_mono;
12 extern GX_FONT _gx_dave2d_system_font_4bpp;
13 extern GX_FONT _gx_dave2d_system_font_mono;
14 }
15 
16 #ifdef _DEBUG
17 #define new DEBUG_NEW
18 #endif
19 
20 CString ResourceCommentBlock(""
21     "/*******************************************************************************/\n"
22     "/*  This file is auto-generated by Azure RTOS GUIX Studio. Do not edit this    */\n"
23     "/*  file by hand. Modifications to this file should only be made by running    */\n"
24     "/*  the Azure RTOS GUIX Studio application and re-generating the application   */\n"
25     "/*  resource file(s). For more information please refer to the Azure RTOS GUIX */\n"
26     "/*  Studio User Guide, or visit our web site at azure.com/rtos                 */\n"
27     "/*                                                                             */\n"
28 );
29 
30 #define COLUMN_WIDTH 80
31 #define GX_CONVERT_VER    1
32 #define GX_CONVERT_SUBVER 0
33 
34 static TCHAR *strColorFormat51[] = {
35 	_T(""),
36 	_T("GX_COLOR_FORMAT_MONOCHROME"),
37 	_T("GX_COLOR_FORMAT_MONOCHROME_INVERTED"),
38 	_T("GX_COLOR_FORMAT_2BIT_GRAY"),
39 	_T("GX_COLOR_FORMAT_2BIT_GRAY_INVERTED"),
40 	_T("GX_COLOR_FORMAT_4BIT_GRAY"),
41 	_T("GX_COLOR_FORMAT_4BIT_GRAY_INVERTED"),
42 	_T("GX_COLOR_FORMAT_4BIT_VGA"),
43 	_T("GX_COLOR_FORMAT_8BIT_GRAY"),
44 	_T("GX_COLOR_FORMAT_8BIT_GRAY_INVERTED"),
45 	_T("GX_COLOR_FORMAT_8BIT_PALETTE"),
46 	_T("GX_COLOR_FORMAT_8BIT_PACKED_PIXEL"),
47 	_T("GX_COLOR_FORMAT_15BIT_BGR"),
48 	_T("GX_COLOR_FORMAT_15BIT_RGB"),
49 	_T("GX_COLOR_FORMAT_16BIT_RGB"),
50     _T("GX_COLOR_FORMAT_16BIT_ARGB"),
51     _T("GX_COLOR_FORMAT_16BIT_BGRA"),
52 	_T("GX_COLOR_FORMAT_16BIT_BGR"),
53 	_T("GX_COLOR_FORMAT_24BIT_RGB"),
54 	_T("GX_COLOR_FORMAT_24BIT_BGR"),
55 	_T("GX_COLOR_FORMAT_24BIT_XRGB"),
56 	_T("GX_COLOR_FORMAT_24BIT_BGRX"),
57 	_T("GX_COLOR_FORMAT_32BIT_ARGB"),
58 	_T("GX_COLOR_FORMAT_32BIT_RGBA"),
59 	_T("GX_COLOR_FORMAT_32BIT_ABGR"),
60 	_T("GX_COLOR_FORMAT_32BIT_BGRA"),
61 };
62 
63 static TCHAR *strColorFormat52[] = {
64 	_T(""),
65 	_T("GX_COLOR_FORMAT_MONOCHROME"),
66 	_T("GX_COLOR_FORMAT_MONOCHROME_INVERTED"),
67 	_T("GX_COLOR_FORMAT_2BIT_GRAY"),
68 	_T("GX_COLOR_FORMAT_2BIT_GRAY_INVERTED"),
69 	_T("GX_COLOR_FORMAT_4BIT_GRAY"),
70 	_T("GX_COLOR_FORMAT_4BIT_GRAY_INVERTED"),
71 	_T("GX_COLOR_FORMAT_4BIT_VGA"),
72 	_T("GX_COLOR_FORMAT_8BIT_GRAY"),
73 	_T("GX_COLOR_FORMAT_8BIT_GRAY_INVERTED"),
74 	_T("GX_COLOR_FORMAT_8BIT_PALETTE"),
75 	_T("GX_COLOR_FORMAT_8BIT_PACKED_PIXEL"),
76 	_T("GX_COLOR_FORMAT_5551BGRX"),
77 	_T("GX_COLOR_FORMAT_1555XRGB"),
78 	_T("GX_COLOR_FORMAT_565RGB"),
79     _T("GX_COLOR_FORMAT_4444ARGB"),
80     _T("GX_COLOR_FORMAT_4444BGRA"),
81 	_T("GX_COLOR_FORMAT_565BGR"),
82 	_T("GX_COLOR_FORMAT_24RGB"),
83 	_T("GX_COLOR_FORMAT_24BGR"),
84 	_T("GX_COLOR_FORMAT_24XRGB"),
85 	_T("GX_COLOR_FORMAT_24BGRX"),
86 	_T("GX_COLOR_FORMAT_32ARGB"),
87 	_T("GX_COLOR_FORMAT_32RGBA"),
88 	_T("GX_COLOR_FORMAT_32ABGR"),
89 	_T("GX_COLOR_FORMAT_32BGRA"),
90     _T("GX_COLOR_FORMAT_8BIT_ALPHAMAP"),
91 };
92 
93 #define NUM_COLOR_FORMATS (sizeof(strColorFormat52) / sizeof(TCHAR *))
94 
95 #define IS_RX_TARGET      (m_project->mHeader.target_cpu == CPU_RX)
96 #define IS_RZ_TARGET      (m_project->mHeader.target_cpu == CPU_RZ)
97 #define IS_GNU_TOOLS      (m_project->mHeader.target_tools == TOOLS_GNU)
98 #define IS_IAR_TOOLS      (m_project->mHeader.target_tools == TOOLS_IAR)
99 
100 ////////////////////////////////////////////////////////////////////////////////////////////////
resource_gen(studiox_project * proj)101 resource_gen::resource_gen(studiox_project *proj)
102 {
103     m_project = proj;
104     m_num_displays = m_project->mHeader.num_displays;
105     mUsingDefault8BitFont = FALSE;
106     mUsingDefault4BitFont = FALSE;
107     mUsingDefaultMonoFont = FALSE;
108 
109     if (GetCmdInfo()->IsNoGui())
110     {
111         m_big_endian = GetCmdInfo()->IsBigEndian();
112     }
113     else
114     {
115         m_big_endian = m_project->mHeader.big_endian;
116     }
117 
118     mp_bin_generater = NULL;
119     m_warn_on_error = FALSE;
120 }
121 
122 ///////////////////////////////////////////////////////////////////////////////
123 //
124 // IsRotatedResourceSupported
125 //
126 // Static function used by resource_gen, binary_resource_gen, and
127 // screen generator to determine if screen rotation support is enabled.
128 ///////////////////////////////////////////////////////////////////////////////
129 
IsRotatedResourceSupported(studiox_project * project,int display)130 BOOL resource_gen::IsRotatedResourceSupported(studiox_project *project, int display)
131 {
132     #if !defined(ENABLE_RENESAS_DAVE2D_DISPLAY_ROTATION)
133     if (project->mHeader.target_cpu == CPU_SYNERGY)
134     {
135         return FALSE;
136     }
137     #endif
138 
139     if (project->mDisplays[display].rotation_angle == GX_SCREEN_ROTATION_CW ||
140         project->mDisplays[display].rotation_angle == GX_SCREEN_ROTATION_CCW)
141     {
142         switch (project->mDisplays[display].colorformat)
143         {
144         case GX_COLOR_FORMAT_565RGB:
145             if (project->mHeader.guix_version >= GX_VERSION_DISPLAY_ROTATION)
146             {
147                 return TRUE;
148             }
149             break;
150 
151         case GX_COLOR_FORMAT_8BIT_PALETTE:
152             if (project->mHeader.guix_version >= GX_VERSION_8BIT_PALETTE_DISPLAY_ROTATION)
153             {
154                 return TRUE;
155             }
156             break;
157 
158         case GX_COLOR_FORMAT_24XRGB:
159         case GX_COLOR_FORMAT_32ARGB:
160             if (project->mHeader.guix_version >= GX_VERSION_8BIT_PALETTE_DISPLAY_ROTATION)
161             {
162                 return TRUE;
163             }
164             break;
165         }
166     }
167 
168     return FALSE;
169 }
170 
171 
172 
173 ////////////////////////////////////////////////////////////////////////////////////////////////
SetOutFile(CString filename,BOOL binary_mode)174 BOOL resource_gen::SetOutFile(CString filename, BOOL binary_mode)
175 {
176     CString pathname;
177     PATHINFO info;
178 
179     CString outfile = m_project->mHeader.resource_path;
180     if (outfile.GetAt(outfile.GetLength() - 1) != '\\')
181     {
182         outfile += '\\';
183     }
184     outfile += filename;
185 
186     if (outfile.GetAt(1) != ':')
187     {
188         ConvertToProjectRelativePath(outfile);
189 
190         info.pathname = outfile;
191         info.pathtype = PATH_TYPE_PROJECT_RELATIVE;
192 
193         outfile = MakeAbsolutePathname(info);
194     }
195 
196     if (!CheckOutputFileSecurity(outfile, binary_mode))
197     {
198         return FALSE;
199     }
200 
201     for (int index = 0; index < outfile_list.GetCount(); index++)
202     {
203         m_outfile = outfile_list.GetAt(index);
204 
205         pathname = m_outfile->GetFilePath();
206 
207         if (!outfile.Compare(pathname))
208         {
209             m_written_size = (ULONG)m_outfile->GetLength();
210 
211             return TRUE;
212         }
213     }
214 
215     m_outfile = new CFile();
216     m_written_size = 0;
217     if (!m_outfile->Open(outfile, CFile::modeCreate | CFile::modeWrite))
218     {
219         CString msg;
220         msg.Format(_T("Could not open output file:\n%s\nPlease check resource file path."), outfile);
221         ErrorMsg(msg);
222         delete m_outfile;
223         return FALSE;
224     }
225 
226     outfile_list.Add(m_outfile);
227 
228     if (binary_mode)
229     {
230         ((binary_resource_gen *)this)->WriteStandaloneResHeader();
231     }
232     else
233     {
234         WriteCommentBlock(ResourceCommentBlock);
235         CString out;
236 
237         if (m_project->mHeader.insert_headers_before)
238         {
239             // Insert additional headers before any other includes
240             WriteAdditionalHeaders(m_project->mHeader.additional_headers);
241         }
242 
243         out.Format(_T("#include \"gx_api.h\"\n#include \"%s.h\"\n"), GetResourceFileName());
244         FileWrite(out);
245 
246         if (!m_project->mHeader.insert_headers_before)
247         {
248             //Insert additional headers after any other includes
249             WriteAdditionalHeaders(m_project->mHeader.additional_headers);
250         }
251     }
252 
253     return TRUE;
254 }
255 
256 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteErrorDirectives()257 void resource_gen::WriteErrorDirectives()
258 {
259     CCommandInfo *pCmdInfo = GetCmdInfo();
260     BOOL enabled;
261     BOOL UTF8 = FALSE;
262     BOOL EXTENDED_UNICODE = FALSE;
263     BOOL KERNING = FALSE;
264     CString out;
265 
266     for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
267     {
268         m_ThemeName = m_project->mDisplays[m_display].themes[theme].theme_name;
269 
270         if (pCmdInfo->IsNoGui())
271         {
272             enabled = pCmdInfo->IsThemeEnabled(m_ThemeName);
273         }
274         else
275         {
276             enabled = m_project->mDisplays[m_display].themes[theme].gen_font_table;
277         }
278 
279         if (!enabled) continue;
280 
281         int font_id;
282 
283         for (font_id = 0; font_id < m_project->CountResources(m_display, RES_TYPE_FONT); font_id++)
284         {
285             res_info *info = m_project->FindResource(m_display, theme, RES_TYPE_FONT, font_id);
286 
287             if (info)
288             {
289                 if (!KERNING && info->font_kerning)
290                 {
291                     KERNING = TRUE;
292                 }
293 
294                 if ((!UTF8 || !EXTENDED_UNICODE) && !(info->is_default && info->pathinfo.pathname.IsEmpty()))
295                 {
296                     if (info->font_support_extended_unicode)
297                     {
298                         EXTENDED_UNICODE = TRUE;
299                         UTF8 = TRUE;
300                     }
301                     else
302                     {
303 
304                         GX_FONT *next_page = m_optimized_fonts[theme].GetAt(font_id);
305 
306                         if(!next_page)
307                         {
308                             next_page = MakeOptimizedFont(info, m_display, m_warn_on_error);
309 
310                             if (!next_page)
311                             {
312                                 m_warn_on_error = FALSE;
313                             }
314 
315                             // Reserve optimized font for later use.
316                         	m_optimized_fonts[theme].SetAt(font_id, next_page);
317                         }
318 
319                         while (next_page)
320                         {
321                             if (next_page->gx_font_last_glyph > 0xffff)
322                             {
323                                 EXTENDED_UNICODE = TRUE;
324                                 UTF8 = TRUE;
325                                 break;
326                             }
327                             else if (next_page->gx_font_last_glyph > 0xff)
328                             {
329                                 UTF8 = TRUE;
330                             }
331 
332                             next_page = (GX_FONT *)next_page->gx_font_next_page;
333                         }
334                     }
335                 }
336             }
337         }
338 
339         if (EXTENDED_UNICODE && KERNING)
340         {
341             break;
342         }
343     }
344 
345     out = "";
346     if (UTF8)
347     {
348         out += _T("\n#if !defined(GX_UTF8_SUPPORT)\n");
349         out += _T("#error \"The symbol GX_UTF8_SUPPORT must be defined to support the Studio project settings\".\n");
350         out += _T("#endif\n");
351     }
352 
353     if (EXTENDED_UNICODE)
354     {
355         out += _T("#if !defined(GX_EXTENDED_UNICODE_SUPPORT)\n");
356         out += _T("#error \"The symbol GX_EXTENDED_UNICODE_SUPPORT must be defined to support the Studio project settings\".\n");
357         out += _T("#endif\n");
358     }
359 
360     if (KERNING)
361     {
362         out += _T("#if !defined(GX_FONT_KERNING_SUPPORT)\n");
363         out += _T("#error \"The symbol GX_FONT_KERNING_SUPPORT must be defined if \'Generate kerning info\' is selected in font edit dialog\".\n");
364         out += _T("#endif\n");
365     }
366 
367     FileWrite(out);
368 }
369 
370 ////////////////////////////////////////////////////////////////////////////////////////////////
CalculateTableSizes()371 void resource_gen::CalculateTableSizes()
372 {
373     /* Calculate the size of color table, font table and pixelmap table. */
374     m_color_table_size = m_font_table_size = m_pixelmap_table_size = 0;
375     int active_theme = m_project->mDisplays[m_display].active_theme;
376     int res_id;
377     res_info *info;
378     m_color_table_size = m_project->CountResources(m_display, RES_TYPE_COLOR);
379 
380     for (res_id = 0; res_id < m_project->CountResources(m_display, RES_TYPE_FONT); res_id++)
381     {
382         info = m_project->FindResource(m_display, active_theme, RES_TYPE_FONT, res_id);
383 
384         if (IsResEnabled(info) && (!info->output_file_enabled || !info->binary_mode))
385         {
386             m_font_table_size++;
387         }
388     }
389 
390     m_pixelmap_table_size = 1;
391 
392     for (res_id = 1; res_id <= m_project->CountResources(m_display, RES_TYPE_PIXELMAP); res_id++)
393     {
394         info = m_project->FindResource(m_display, active_theme, RES_TYPE_PIXELMAP, res_id);
395 
396         if ((IsResEnabled(info) && (!info->output_file_enabled || !info->binary_mode)) || IsSystemPixelmap(res_id))
397         {
398             m_pixelmap_table_size += info->GetPixelmapFrameCount();
399         }
400     }
401 }
402 
403 ///////////////////////////////////////////////////////////////////////////////
IsStringReferencedbyMlView(widget_info * info,GX_RESOURCE_ID resource_id)404 BOOL resource_gen::IsStringReferencedbyMlView(widget_info* info, GX_RESOURCE_ID resource_id)
405 {
406     while (info)
407     {
408 
409         if ((info->basetype == GX_TYPE_MULTI_LINE_TEXT_VIEW) &&
410             (info->string_id[0] == resource_id))
411         {
412             return TRUE;
413         }
414 
415         if (IsStringReferencedbyMlView(info->GetChildWidgetInfo(), resource_id))
416         {
417             return TRUE;
418         }
419 
420         info = info->GetNextWidgetInfo();
421     }
422     return FALSE;
423 }
424 
425 ////////////////////////////////////////////////////////////////////////////////////////////////
GenerateResourceFile(int display)426 BOOL resource_gen::GenerateResourceFile(int display)
427 {
428     m_display = display;
429     mDefaultPaletteWritten = FALSE;
430 
431     GotoProjectDirectory();
432 
433     // for now just use project name for output name
434     CCommandInfo *pCmdInfo = GetCmdInfo();
435     CString res_file_name;
436     BOOL    gen_res_header;
437 
438     if (m_outfile)
439     {
440         delete m_outfile;
441     }
442 
443     InitOptimizedFonts();
444 
445     m_outfile = new CFile();
446 
447     CalculateTableSizes();
448 
449     if (pCmdInfo->IsNoGui())
450     {
451         gen_res_header = pCmdInfo->GenResHeader();
452     }
453     else
454     {
455         gen_res_header = m_project->mHeader.gen_res_header;
456     }
457 
458     m_project->CopyDictionary(m_display, RES_TYPE_PIXELMAP, &m_pixelmap_dictionary);
459     m_project->SortResDictionary(RES_TYPE_PIXELMAP, &m_pixelmap_dictionary);
460 
461     if (gen_res_header)
462     {
463         res_file_name = m_project->mHeader.header_path;
464         if (!res_file_name.IsEmpty())
465         {
466             if (res_file_name.GetAt(res_file_name.GetLength() - 1) != '\\')
467             {
468                 res_file_name += "\\";
469             }
470         }
471 
472         res_file_name += GetResourceFileName() + _T(".h");
473         if (!CheckOutputFileSecurity(res_file_name))
474         {
475             return FALSE;
476         }
477 
478         /* Generate head file. */
479         if (!m_outfile->Open(res_file_name, CFile::modeCreate | CFile::modeWrite))
480         {
481             CString msg;
482             msg.Format(_T("Could not open output file:\n%s\nPlease check resource file path."), res_file_name);
483 
484             ErrorMsg(msg);
485             delete m_outfile;
486             DestroyOptimizedFonts();
487             return FALSE;
488         }
489 
490         GenerateResourceHeader();
491         m_outfile->Close();
492     }
493 
494     res_file_name = m_project->mHeader.resource_path;
495     if (!res_file_name.IsEmpty())
496     {
497         if (res_file_name.GetAt(res_file_name.GetLength() - 1) != '\\')
498         {
499             res_file_name += "\\";
500         }
501     }
502 
503     res_file_name += GetResourceFileName() + _T(".c");
504 
505     /* Generate c file. */
506     if (!m_outfile->Open(res_file_name, CFile::modeCreate | CFile::modeWrite))
507     {
508         CString msg;
509         msg.Format(_T("Could not open output file:\n%s\nPlease check resource file path."), res_file_name);
510 
511         ErrorMsg(msg);
512         EndBusyMsg();
513         delete m_outfile;
514         DestroyOptimizedFonts();
515         return FALSE;
516     }
517     outfile_list.Add(m_outfile);
518 
519     if (pCmdInfo->IsXmlMode())
520     {
521         WriteFontData();
522         WritePixelmapData();
523     }
524     else
525     {
526         GenerateResourceData();
527     }
528     DestroyOptimizedFonts();
529     CloseOutputFiles();
530 
531     if (mp_bin_generater)
532     {
533         mp_bin_generater->DestroyResource();
534         delete mp_bin_generater;
535         mp_bin_generater = NULL;
536     }
537 
538     return TRUE;
539 }
540 
541 ////////////////////////////////////////////////////////////////////////////////////////////////
CloseOutputFiles()542 void resource_gen::CloseOutputFiles()
543 {
544     for (int index = 0; index < outfile_list.GetCount(); index++)
545     {
546         m_outfile = outfile_list.GetAt(index);
547         m_outfile->Close();
548         delete m_outfile;
549     }
550     m_outfile = NULL;
551     outfile_list.RemoveAll();
552 }
553 
554 ////////////////////////////////////////////////////////////////////////////////////////////////
UpperProjectName()555 CString resource_gen::UpperProjectName()
556 {
557     CString name(m_project->mHeader.project_name);
558     name.MakeUpper();
559     return name;
560 }
561 
562 
563 ////////////////////////////////////////////////////////////////////////////////////////////////
UpperProjDisplayName()564 CString resource_gen::UpperProjDisplayName()
565 {
566     CString name(m_project->mHeader.project_name);
567     name += "_";
568     name += m_project->mDisplays[m_display].name;
569     name.MakeUpper();
570     return name;
571 }
572 
573 ////////////////////////////////////////////////////////////////////////////////////////////////
GenerateResourceHeader()574 BOOL resource_gen::GenerateResourceHeader()
575 {
576     WriteCommentBlock(ResourceCommentBlock);
577 
578     CString out;
579     CString name;
580 
581     name = UpperProjDisplayName();
582 
583     out.Format(_T("#ifndef _%s_RESOURCES_H_\n#define _%s_RESOURCES_H_\n\n"), name, name);
584     FileWrite(out);
585     FileWrite(CString("#include \"gx_api.h\"\n"));
586 
587     WriteErrorDirectives();
588 
589     WriteDisplayDefines();
590     WriteThemeDefines();
591     WriteLanguageDefines();
592 
593     WriteColorDefines();
594     WriteFontDefines();
595     WritePixelmapDefines();
596 
597     WriteStringDefines();
598 
599     FileWrite(CString("\n#endif      /* sentry */\n"));
600 
601     return TRUE;
602 }
603 
604 ////////////////////////////////////////////////////////////////////////////////////////////////
GenerateResourceData()605 BOOL resource_gen::GenerateResourceData()
606 {
607     string_table *table = GetActiveStringTable();
608     if (table)
609     {
610         table->GenerateCleanCharacterMap();
611     }
612     WriteCommentBlock(ResourceCommentBlock);
613     CString out;
614 
615     if (m_project->mHeader.insert_headers_before)
616     {
617         //Insert additional headers before any other includes
618         WriteAdditionalHeaders(m_project->mHeader.additional_headers);
619     }
620 
621     out.Format(_T("#include \"gx_api.h\"\n#include \"%s.h\"\n"), GetResourceFileName());
622     FileWrite(out);
623 
624     if (!m_project->mHeader.insert_headers_before)
625     {
626         WriteAdditionalHeaders(m_project->mHeader.additional_headers);
627     }
628 
629     WriteColorTable();
630     WriteFontData();
631     WriteFontTable();
632     WritePixelmapData();
633     WritePixelmapTable();
634     WriteStringData();
635     WriteStringTable();
636 
637     WriteThemes();
638 
639     return TRUE;
640 }
641 
642 ////////////////////////////////////////////////////////////////////////////////////////////////
InitOptimizedFonts()643 void resource_gen::InitOptimizedFonts()
644 {
645     int font_count = m_project->CountResources(m_display, RES_TYPE_FONT);
646     for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
647     {
648         m_optimized_fonts[theme].RemoveAll();
649 
650         for (int index = 0; index < font_count; index++)
651         {
652             m_optimized_fonts[theme].Add(GX_NULL);
653         }
654     }
655 }
656 
657 ////////////////////////////////////////////////////////////////////////////////////////////////
DestroyOptimizedFonts()658 void resource_gen::DestroyOptimizedFonts()
659 {
660     GX_FONT* font;
661 
662     for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
663     {
664         for (int index = 0; index < m_optimized_fonts[theme].GetCount(); index++)
665         {
666             font = m_optimized_fonts[theme].GetAt(index);
667             if (font)
668             {
669                 DestroyFont(font);
670             }
671         }
672     }
673 }
674 
675 ////////////////////////////////////////////////////////////////////////////////////////////////
GetColorFormatTable(studiox_project * project)676 TCHAR **resource_gen::GetColorFormatTable(studiox_project *project)
677 {
678     TCHAR** format_name = strColorFormat52;
679 
680     /* switch for backward compatibility */
681     if (project->mHeader.guix_version < 50200)
682     {
683         format_name = strColorFormat51;
684     }
685 
686     return format_name;
687 }
688 ////////////////////////////////////////////////////////////////////////////////////////////////
GetColorFormatName(int color_format)689 TCHAR *resource_gen::GetColorFormatName(int color_format)
690 {
691     if (color_format >= NUM_COLOR_FORMATS)
692     {
693         ErrorMsg("Invalid color format in project header");
694         return(_T("INVALID_FORMAT"));
695     }
696 
697     studiox_project* project = GetOpenProject();
698 
699     if (!project)
700     {
701         return L"";
702     }
703 
704     return(GetColorFormatTable(project)[color_format]);
705 }
706 
707 ////////////////////////////////////////////////////////////////////////////////////////////////
GetColorFormatVal(CString name)708 int resource_gen::GetColorFormatVal(CString name)
709 {
710     if (name.IsEmpty())
711     {
712         return 0;
713     }
714 
715     studiox_project* project = GetOpenProject();
716 
717     if (!project)
718     {
719         return 0;
720     }
721 
722     TCHAR** table = GetColorFormatTable(project);
723 
724     for(int index = 0; index < NUM_COLOR_FORMATS; index++)
725     {
726         if (CString(table[index]) == name)
727         {
728             return index;
729         }
730     }
731 
732     return 0;
733 }
734 
735 
736 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteDisplayDefines()737 void resource_gen::WriteDisplayDefines()
738 {
739     CString out;
740 
741     WriteComment("Display and theme definitions");
742 
743     out.Format(_T("#define %s %d\n"), UpperDisplayName(), m_display);
744     FileWrite(out);
745 
746     out.Format(_T("#define %s_COLOR_FORMAT %s\n"), UpperDisplayName(), GetColorFormatName(m_project->mDisplays[m_display].colorformat));
747     FileWrite(out);
748 
749     out.Format(_T("#define %s_X_RESOLUTION %d\n"), UpperDisplayName(), m_project->mDisplays[m_display].xres);
750     FileWrite(out);
751     out.Format(_T("#define %s_Y_RESOLUTION %d\n"), UpperDisplayName(), m_project->mDisplays[m_display].yres);
752     FileWrite(out);
753 }
754 
755 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteThemeDefines()756 void resource_gen::WriteThemeDefines()
757 {
758     /* Pickup command info class instance. */
759     CCommandInfo *pCmdInfo = GetCmdInfo();
760     theme_info *info;
761     CString theme_name;
762     BOOL enabled;
763     CString out;
764     int theme_count = 0;
765 
766     for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
767     {
768         info = &(m_project->mDisplays[m_display].themes[theme]);
769         theme_name = info->theme_name;
770 
771         if (pCmdInfo->IsNoGui())
772         {
773             enabled = pCmdInfo->IsThemeEnabled(theme_name);
774         }
775         else
776         {
777             enabled = info->enabled;
778         }
779 
780         // Include the definitions of enabled themes
781         if (enabled)
782         {
783 
784             theme_name.MakeUpper();
785             out.Format(_T("#define %s_%s %d\n"), UpperDisplayName(), theme_name, theme_count);
786             FileWrite(out);
787 
788             theme_count++;
789         }
790     }
791 
792     if (m_project->mHeader.guix_version > 50302)
793     {
794         if (theme_count)
795         {
796             out.Format(_T("#define %s_THEME_TABLE_SIZE %d\n"), UpperDisplayName(), theme_count);
797             FileWrite(out);
798         }
799     }
800 }
801 
802 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteLanguageDefines()803 void resource_gen::WriteLanguageDefines()
804 {
805     CString out;
806 
807     INT language_count = 0;
808 
809     WriteComment("Language definitions");
810 
811     /* Pickup command info class instance. */
812     CCommandInfo *pCmdInfo = GetCmdInfo();
813     CString lang_name;
814     BOOL enabled;
815     CString display_name;
816 
817     if (m_project->mHeader.num_displays > 1)
818     {
819         display_name = UpperDisplayName() + _T("_");
820     }
821     else
822     {
823         display_name = _T("");
824     }
825 
826     for (int language = 0; language < m_project->mHeader.num_languages; language++)
827     {
828         lang_name = m_project->mHeader.languages[language].name;
829 
830         if (pCmdInfo->IsNoGui())
831         {
832             enabled = pCmdInfo->IsLanguageEnabled(lang_name);
833         }
834         else
835         {
836             enabled = m_project->mDisplays[m_display].gen_string_table[language];
837         }
838 
839         /* Include the definicions of enabled languages. */
840         if(enabled)
841         {
842             lang_name.MakeUpper();
843 
844             out.Format(_T("#define %sLANGUAGE_%s %d\n"), display_name, lang_name, language_count);
845             FileWrite(out);
846 
847             language_count++;
848         }
849     }
850 
851     if (language_count)
852     {
853         out.Format(_T("#define %s_LANGUAGE_TABLE_SIZE %d\n"), UpperDisplayName(), language_count);
854         FileWrite(out);
855     }
856 }
857 
858 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteColorDefines(void)859 void resource_gen::WriteColorDefines(void)
860 {
861     int color_id;
862     int active_theme = m_project->mDisplays[m_display].active_theme;
863     WriteComment("Color ID definitions");
864     CString out;
865     CString res_name;
866     CString upper_name;
867     CString display_name = UpperDisplayName();
868     BOOL gen_system_color_ids = FALSE;
869 
870     if (project_lib_version() < GX_VERSION_RESOURCE_ID_GENERATE_FIX)
871     {
872         gen_system_color_ids = TRUE;
873     }
874 
875 
876     for (color_id = 0; color_id < m_project->CountResources(m_display, RES_TYPE_COLOR); color_id++)
877     {
878         res_info *info = m_project->FindResource(m_display, active_theme, RES_TYPE_COLOR, color_id);
879         if (info)
880         {
881             upper_name = CString(info->name);
882             upper_name.MakeUpper();
883 
884             if (info->is_default)
885             {
886                 if ((m_display == 0) && gen_system_color_ids)
887                 {
888                     out.Format(_T("#define GX_COLOR_ID_%s %d\n"), upper_name, color_id);
889                     FileWrite(out);
890                 }
891             }
892             else
893             {
894                 if (m_num_displays > 1)
895                 {
896                     out.Format(_T("#define GX_COLOR_ID_%s_%s %d\n"), display_name, upper_name, color_id);
897                 }
898                 else
899                 {
900                     out.Format(_T("#define GX_COLOR_ID_%s %d\n"), upper_name, color_id);
901                 }
902                 FileWrite(out);
903             }
904         }
905     }
906 
907     out.Format(_T("#define %s_COLOR_TABLE_SIZE %d\n"),
908         display_name, m_color_table_size);
909     FileWrite(out);
910 }
911 
912 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteColorTable(void)913 void resource_gen::WriteColorTable(void)
914 {
915     int color_id;
916     res_info *info;
917     WriteComment("Color Table");
918     CString out;
919     GX_COLOR rgb_color;
920     GX_COLOR native_color;
921     int color_format;
922 
923     color_format = m_project->mDisplays[m_display].colorformat;
924 
925     CCommandInfo *pCmdInfo = GetCmdInfo();
926     BOOL enabled;
927 
928     for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
929     {
930         if (pCmdInfo->IsNoGui())
931         {
932             enabled = pCmdInfo->IsThemeEnabled(m_project->mDisplays[m_display].themes[theme].theme_name);
933         }
934         else
935         {
936             enabled = m_project->mDisplays[m_display].themes[theme].gen_color_table;
937         }
938 
939         if (!enabled) continue;
940 
941         out.Format(_T("GX_CONST GX_COLOR %s_%s_color_table[] =\n{\n"),
942             m_project->mDisplays[m_display].name,
943             m_project->mDisplays[m_display].themes[theme].theme_name);
944         FileWrite(out);
945 
946         int end_id = m_project->CountResources(m_display, RES_TYPE_COLOR);
947         BOOL bFirstColor = TRUE;
948 
949         for (color_id = 0; color_id < end_id; color_id++)
950         {
951             info = m_project->FindResource(m_display, theme, RES_TYPE_COLOR, color_id);
952 
953             if (info)
954             {
955                 rgb_color = info->colorval;
956                 native_color = resource_view::GetNativeColor(rgb_color, color_format);
957 
958                 if (bFirstColor)
959                 {
960                     out.Format(_T("    0x%08x"), native_color);
961                     bFirstColor = FALSE;
962                 }
963                 else
964                 {
965                     out.Format(_T(",\n    0x%08x"), native_color);
966                 }
967                 FileWrite(out);
968             }
969         }
970         out.Format(_T("\n};\n\n"));
971         FileWrite(out);
972 
973         /* Olny write palette for 8bit palette driver for now.
974            4bpp driver contains palette table. But should not write it to file. */
975         if (color_format == GX_COLOR_FORMAT_8BIT_PALETTE &&
976             m_project->mDisplays[m_display].themes[theme].palette)
977         {
978             WritePalette(theme);
979             mDefaultPaletteWritten = TRUE;
980         }
981     }
982 }
983 
984 ////////////////////////////////////////////////////////////////////////////////////////////////
WritePalette(int theme)985 void resource_gen::WritePalette(int theme)
986 {
987     GX_COLOR *palette;
988     int palette_size;
989 
990     // make sure the optimal palette is up to date:
991     m_project->CreateThemePalette(m_display, theme, NULL);
992 
993     // CreateThemePalette() updates the display.themes.palette
994 
995     palette_size = m_project->mDisplays[m_display].themes[theme].palette_total_size;
996     palette =  m_project->mDisplays[m_display].themes[theme].palette;
997 
998     WritePalette(palette_size, palette, m_project->mDisplays[m_display].themes[theme].theme_name);
999 }
1000 
1001 ////////////////////////////////////////////////////////////////////////////////////////////////
WritePalette(int palette_size,GX_COLOR * palette,CString & pal_name)1002 void resource_gen::WritePalette(int palette_size, GX_COLOR *palette,
1003     CString &pal_name)
1004 {
1005     CString out;
1006     int palette_index;
1007 
1008     WriteComment("Color Palette");
1009     GX_COLOR rgb_color;
1010 
1011     if (palette == NULL || palette_size == 0)
1012     {
1013         return;
1014     }
1015 
1016     out.Format(_T("GX_CONST GX_COLOR %s_%s_palette[%d] =\n{\n"),
1017          m_project->mDisplays[m_display].name, pal_name, palette_size);
1018     FileWrite(out);
1019 
1020     for (palette_index = 0; palette_index < palette_size; palette_index++)
1021     {
1022         rgb_color = palette[palette_index];
1023 
1024         if (palette_index < palette_size - 1)
1025         {
1026             out.Format(_T("    0x%08x,\n"), rgb_color);
1027         }
1028         else
1029         {
1030             out.Format(_T("    0x%08x\n"), rgb_color);
1031         }
1032         FileWrite(out);
1033     }
1034     out.Format(_T("};\n\n"));
1035     FileWrite(out);
1036 }
1037 
1038 
1039 ////////////////////////////////////////////////////////////////////////////////////////////////
UpperDisplayName()1040 CString resource_gen::UpperDisplayName()
1041 {
1042     CString upper_name =  m_project->mDisplays[m_display].name;
1043     upper_name.MakeUpper();
1044     return upper_name;
1045 }
1046 
1047 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteFontDefines(void)1048 void resource_gen::WriteFontDefines(void)
1049 {
1050     int font_id;
1051     int active_theme = m_project->mDisplays[m_display].active_theme;
1052     WriteComment("Font ID definitions");
1053     CString out;
1054     CString upper_name;
1055     BOOL gen_system_font_ids = FALSE;
1056 
1057     if (project_lib_version() < GX_VERSION_RESOURCE_ID_GENERATE_FIX)
1058     {
1059         gen_system_font_ids = TRUE;
1060     }
1061 
1062     for (font_id = 0; font_id < m_project->CountResources(m_display, RES_TYPE_FONT); font_id++)
1063     {
1064         res_info *info = m_project->FindResource(m_display, active_theme, RES_TYPE_FONT, font_id);
1065         if (info && (!info->output_file_enabled || !info->binary_mode))
1066         {
1067             CString upper_name(info->name);
1068             upper_name.MakeUpper();
1069 
1070             if (info->is_default)
1071             {
1072                 if ((m_display == 0) && gen_system_font_ids)
1073                 {
1074                     out.Format(_T("#define GX_FONT_ID_%s %d\n"), upper_name, font_id);
1075                     FileWrite(out);
1076                 }
1077             }
1078             else
1079             {
1080                 if (m_num_displays > 1)
1081                 {
1082                     out.Format(_T("#define GX_FONT_ID_%s_%s %d\n"), UpperDisplayName(), upper_name, font_id);
1083                 }
1084                 else
1085                 {
1086                     out.Format(_T("#define GX_FONT_ID_%s %d\n"), upper_name, font_id);
1087                 }
1088                 FileWrite(out);
1089             }
1090         }
1091     }
1092 
1093     out.Format(_T("#define %s_FONT_TABLE_SIZE %d\n"),
1094        UpperDisplayName(), m_font_table_size);
1095     FileWrite(out);
1096 
1097 }
1098 
1099 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteFontData(void)1100 void resource_gen::WriteFontData(void)
1101 {
1102     int font_id;
1103     mUsingDefault8BitFont = FALSE;
1104     mUsingDefault4BitFont = FALSE;
1105     mUsingDefaultMonoFont = FALSE;
1106 
1107     CCommandInfo *pCmdInfo = GetCmdInfo();
1108     BOOL enabled;
1109 
1110     for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
1111     {
1112         m_ThemeName = m_project->mDisplays[m_display].themes[theme].theme_name;
1113 
1114         if (pCmdInfo->IsNoGui())
1115         {
1116             enabled = pCmdInfo->IsThemeEnabled(m_ThemeName);
1117         }
1118         else
1119         {
1120             enabled = m_project->mDisplays[m_display].themes[theme].gen_font_table;
1121         }
1122 
1123         if (!enabled) continue;
1124 
1125         for (font_id = 0; font_id < m_project->CountResources(m_display, RES_TYPE_FONT); font_id++)
1126         {
1127             res_info *info = m_project->FindResource(m_display, theme, RES_TYPE_FONT, font_id);
1128             CString out;
1129 
1130             if (info)
1131             {
1132                 INT rotation_angle = m_project->mDisplays[m_display].rotation_angle;
1133 
1134                 if (info->is_default &&
1135                     info->pathinfo.pathname.IsEmpty() &&
1136                     !IsRotatedResourceSupported(m_project, m_display))
1137                 {
1138                     switch (info->font_bits)
1139                     {
1140                     case 8:
1141                         mUsingDefault8BitFont = TRUE;
1142                         break;
1143 
1144                     case 4:
1145                         mUsingDefault4BitFont = TRUE;
1146                         break;
1147 
1148                     case 1:
1149                         mUsingDefaultMonoFont = TRUE;
1150                         break;
1151                     }
1152                 }
1153                 else
1154                 {
1155                     if (FindResourceReferenceTheme(info, theme) == -1)
1156                     {
1157                         if ((!info->pathinfo.pathname.IsEmpty()) ||
1158                             (rotation_angle != 0))
1159                         {
1160                             if (info->output_file_enabled)
1161                             {
1162                                 if (info->binary_mode)
1163                                 {
1164                                     if (!mp_bin_generater)
1165                                     {
1166                                         mp_bin_generater = new binary_resource_gen(m_project, BINARY_FILE_FORMAT_BIN_STANDALONE);
1167                                         mp_bin_generater->SetDisplay(m_display);
1168                                         mp_bin_generater->InitResource();
1169                                     }
1170 
1171                                     if (!mp_bin_generater->SetOutFile(info->output_file, info->binary_mode))
1172                                     {
1173                                         return;
1174                                     }
1175 
1176                                     mp_bin_generater->WriteFontBlock(info, font_id, theme);
1177                                     continue;
1178                                 }
1179 
1180                                 if (!SetOutFile(info->output_file))
1181                                 {
1182                                     return;
1183                                 }
1184                             }
1185 
1186                             out.Format(_T("\n/* Font %s_%s Data Definition */\n\n"), m_ThemeName.MakeUpper(), info->name);
1187                             FileWrite(out);
1188                             WriteFont(info, theme, font_id);
1189 
1190                             if (info->output_file_enabled)
1191                             {
1192                                 m_outfile = outfile_list.GetAt(0);
1193                             }
1194                         }
1195                     }
1196                 }
1197             }
1198         }
1199     }
1200 }
1201 
1202 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteFontTable(void)1203 void resource_gen::WriteFontTable(void)
1204 {
1205     int font_id;
1206     WriteComment("Font Table");
1207     CString out;
1208     CString name;
1209 
1210     if (mUsingDefault8BitFont)
1211     {
1212         out = CString("\nextern GX_CONST GX_FONT _gx_system_font_8bpp;\n");
1213         FileWrite(out);
1214     }
1215     if (mUsingDefault4BitFont)
1216     {
1217         if (IsDave2dFontFormat(m_project, m_display))
1218         {
1219             if (m_project->mHeader.target_cpu == CPU_SYNERGY)
1220             {
1221                 out = CString("\nextern GX_CONST GX_FONT _gx_synergy_system_font_4bpp;\n");
1222             }
1223             else
1224             {
1225                 out = CString("\nextern GX_CONST GX_FONT _gx_dave2d_system_font_4bpp;\n");
1226             }
1227         }
1228         else
1229         {
1230             out = CString("\nextern GX_CONST GX_FONT _gx_system_font_4bpp;\n");
1231         }
1232         FileWrite(out);
1233     }
1234     if (mUsingDefaultMonoFont)
1235     {
1236         if (IsDave2dFontFormat(m_project, m_display))
1237         {
1238             if (m_project->mHeader.target_cpu == CPU_SYNERGY)
1239             {
1240                 out = CString("\nextern GX_CONST GX_FONT _gx_synergy_system_font_mono;\n");
1241             }
1242             else
1243             {
1244                 out = CString("\nextern GX_CONST GX_FONT _gx_dave2d_system_font_mono;\n");
1245             }
1246         }
1247         else
1248         {
1249             out = CString("\nextern GX_CONST GX_FONT _gx_system_font_mono;\n");
1250         }
1251         FileWrite(out);
1252     }
1253 
1254     CCommandInfo* pCmdInfo = GetCmdInfo();
1255     BOOL enabled;
1256     int end_id = m_project->CountResources(m_display, RES_TYPE_FONT);
1257     res_info *info;
1258     CString theme_name;
1259     int reference_theme;
1260 
1261     /* Extern fonts that defined in custom output files. */
1262     for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
1263     {
1264         m_ThemeName = m_project->mDisplays[m_display].themes[theme].theme_name;
1265 
1266         if (pCmdInfo->IsNoGui())
1267         {
1268             enabled = pCmdInfo->IsThemeEnabled(m_ThemeName);
1269         }
1270         else
1271         {
1272             enabled = m_project->mDisplays[m_display].themes[theme].gen_font_table;
1273         }
1274 
1275         if (!enabled) continue;
1276 
1277         for (font_id = 0; font_id < end_id; font_id++)
1278         {
1279             info = m_project->FindResource(m_display, theme, RES_TYPE_FONT, font_id);
1280 
1281             if (IsResEnabled(info) && (info->output_file_enabled) && (!info->binary_mode))
1282             {
1283                 theme_name = m_ThemeName;
1284                 reference_theme = FindResourceReferenceTheme(info, theme);
1285                 if (reference_theme >= 0)
1286                 {
1287                     theme_name = m_project->mDisplays[m_display].themes[reference_theme].theme_name;
1288                 }
1289 
1290                 out.Format(_T("extern GX_CONST GX_FONT %s_%s;\n"), theme_name.MakeUpper(), info->name);
1291                 FileWrite(out);
1292             }
1293         }
1294     }
1295 
1296     for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
1297     {
1298         m_ThemeName = m_project->mDisplays[m_display].themes[theme].theme_name;
1299 
1300         if (pCmdInfo->IsNoGui())
1301         {
1302             enabled = pCmdInfo->IsThemeEnabled(m_ThemeName);
1303         }
1304         else
1305         {
1306             enabled = m_project->mDisplays[m_display].themes[theme].gen_font_table;
1307         }
1308 
1309         if (!enabled) continue;
1310 
1311 
1312         name = m_project->mDisplays[m_display].name;
1313         name += "_";
1314         name += m_project->mDisplays[m_display].themes[theme].theme_name;
1315         out.Format(_T("GX_CONST GX_FONT *%s_font_table[] =\n{\n"), name);
1316         FileWrite(out);
1317 
1318         BOOL bFirstFont = TRUE;
1319 
1320         for(font_id = 0; font_id < end_id; font_id++)
1321         {
1322             info = m_project->FindResource(m_display, theme, RES_TYPE_FONT, font_id);
1323 
1324             if (info && (!info->output_file_enabled || !info->binary_mode))
1325             {
1326                 if (info->is_default &&
1327                     info->pathinfo.pathname.IsEmpty() &&
1328                     (!IsRotatedResourceSupported(m_project, m_display)))
1329                 {
1330                     switch (info->font_bits)
1331                     {
1332                     case 8:
1333                         name = "_gx_system_font_8bpp";
1334                         break;
1335 
1336                     case 4:
1337                         if (IsDave2dFontFormat(m_project, m_display))
1338                         {
1339                             if (m_project->mHeader.target_cpu == CPU_SYNERGY)
1340                             {
1341                                 name = "_gx_synergy_system_font_4bpp";
1342                             }
1343                             else
1344                             {
1345                                 name = "_gx_dave2d_system_font_4bpp";
1346                             }
1347                         }
1348                         else
1349                         {
1350                             name = "_gx_system_font_4bpp";
1351                         }
1352                         break;
1353                     case 1:
1354                         if (IsDave2dFontFormat(m_project, m_display))
1355                         {
1356                             if (m_project->mHeader.target_cpu == CPU_SYNERGY)
1357                             {
1358                                 name = "_gx_synergy_system_font_mono";
1359                             }
1360                             else
1361                             {
1362                                 name = "_gx_dave2d_system_font_mono";
1363                             }
1364                         }
1365                         else
1366                         {
1367                             name = "_gx_system_font_mono";
1368                         }
1369                         break;
1370                     }
1371                 }
1372                 else
1373                 {
1374                     theme_name = m_ThemeName;
1375                     reference_theme = FindResourceReferenceTheme(info, theme);
1376                     if (reference_theme >= 0)
1377                     {
1378                         theme_name = m_project->mDisplays[m_display].themes[reference_theme].theme_name;
1379                     }
1380 
1381                     name.Format(_T("%s_%s"), theme_name.MakeUpper(), info->name);
1382                 }
1383 
1384                 if (bFirstFont)
1385                 {
1386                     out.Format(_T("    &%s"), name);
1387                     bFirstFont = FALSE;
1388                 }
1389                 else
1390                 {
1391                     out.Format(_T(",\n    &%s"), name);
1392                 }
1393                 FileWrite(out);
1394             }
1395         }
1396         out.Format(_T("\n};\n"));
1397         FileWrite(out);
1398     }
1399 }
1400 
1401 ////////////////////////////////////////////////////////////////////////////////////////////////
WritePixelmapDefines(void)1402 void resource_gen::WritePixelmapDefines(void)
1403 {
1404     int pixelmap_id;
1405     int output_pixelmap_id = 1;
1406     int active_theme = m_project->mDisplays[m_display].active_theme;
1407     WriteComment("Pixelmap ID definitions");
1408     CString out;
1409     BOOL gen_system_pixelmap_ids = FALSE;
1410 
1411     if (project_lib_version() < GX_VERSION_RESOURCE_ID_GENERATE_FIX)
1412     {
1413         gen_system_pixelmap_ids = TRUE;
1414     }
1415 
1416     res_info *info;
1417     int frame_id;
1418     CString upper;
1419 
1420     for (pixelmap_id = 1; pixelmap_id < m_pixelmap_dictionary.GetCount(); pixelmap_id++)
1421     {
1422         info = m_project->FindResource(m_display, active_theme, RES_TYPE_PIXELMAP, m_pixelmap_dictionary.GetAt(pixelmap_id));
1423 
1424         if (!info)
1425         {
1426             continue;
1427         }
1428 
1429         if (IsResEnabled(info) || IsSystemPixelmap(pixelmap_id))
1430         {
1431             for (frame_id = 0; frame_id < info->GetPixelmapFrameCount(); frame_id++)
1432             {
1433                 if (!info->output_file_enabled || !info->binary_mode)
1434                 {
1435                     // Generate pixlemap definitions for pixelmaps that are statically defined.
1436                     upper = MakePixelmapName(info, frame_id);
1437                     upper.MakeUpper();
1438 
1439                     if (info->is_default)
1440                     {
1441                         if ((m_display == 0) && gen_system_pixelmap_ids)
1442                         {
1443                             out.Format(_T("#define GX_PIXELMAP_ID_%s %d\n"), upper, output_pixelmap_id);
1444                             FileWrite(out);
1445                         }
1446                     }
1447                     else
1448                     {
1449                         if (m_num_displays > 1)
1450                         {
1451                             out.Format(_T("#define GX_PIXELMAP_ID_%s_%s %d\n"), UpperDisplayName(), upper, output_pixelmap_id);
1452                         }
1453                         else
1454                         {
1455                             out.Format(_T("#define GX_PIXELMAP_ID_%s %d\n"), upper, output_pixelmap_id);
1456                         }
1457                         FileWrite(out);
1458                     }
1459                     output_pixelmap_id++;
1460                 }
1461             }
1462         }
1463     }
1464 
1465     out.Format(_T("#define %s_PIXELMAP_TABLE_SIZE %d\n"),
1466         UpperDisplayName(), m_pixelmap_table_size);
1467     FileWrite(out);
1468 }
1469 
1470 ////////////////////////////////////////////////////////////////////////////////////////////////
WritePixelmapData(void)1471 void resource_gen::WritePixelmapData(void)
1472 {
1473     BOOL cpu_synergy = FALSE;
1474     res_info *info;
1475     CCommandInfo *pCmdInfo = GetCmdInfo();
1476     BOOL enabled;
1477 
1478     WriteComment("Pixelmap data definitions");
1479 
1480     for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
1481     {
1482         m_ThemeName = m_project->mDisplays[m_display].themes[theme].theme_name;
1483 
1484         if (pCmdInfo->IsNoGui())
1485         {
1486             enabled = pCmdInfo->IsThemeEnabled(m_ThemeName);
1487         }
1488         else
1489         {
1490             enabled = m_project->mDisplays[m_display].themes[theme].gen_pixelmap_table;
1491         }
1492 
1493         if (!enabled) continue;
1494 
1495         for (int index = 1; index < m_pixelmap_dictionary.GetCount(); index++)
1496         {
1497             info = m_project->FindResource(m_display, theme, RES_TYPE_PIXELMAP, m_pixelmap_dictionary.GetAt(index));
1498 
1499             if (!info)
1500             {
1501                 continue;
1502             }
1503 
1504             mPrivatePaletteWritten = FALSE;
1505 
1506             if (info->GetPixelmapFrameCount() && IsResEnabled(info) && (FindResourceReferenceTheme(info, theme) == -1))
1507             {
1508                 for (int frame_id = 0; frame_id < info->GetPixelmapFrameCount(); frame_id++)
1509                 {
1510                     m_map = info->GetPixelmap(frame_id);
1511 
1512                     if (!m_map)
1513                     {
1514                         continue;
1515                     }
1516 
1517                     if (info->output_file_enabled)
1518                     {
1519                         //Output pixelmap to the specified file
1520                         if (info->binary_mode)
1521                         {
1522                             if (!mp_bin_generater)
1523                             {
1524                                 mp_bin_generater = new binary_resource_gen(m_project, BINARY_FILE_FORMAT_BIN_STANDALONE);
1525                                 mp_bin_generater->SetDisplay(m_display);
1526                                 mp_bin_generater->InitResource();
1527                             }
1528 
1529                             if (!mp_bin_generater->SetOutFile(info->output_file, info->binary_mode))
1530                             {
1531                                 return;
1532                             }
1533 
1534                             mp_bin_generater->WritePixelmapBlock(info, 0, 0, theme, frame_id);
1535                             continue;
1536                         }
1537 
1538                         if (!SetOutFile(info->output_file))
1539                         {
1540                             return;
1541                         }
1542                     }
1543 
1544                     if (info->raw)
1545                     {
1546                         // special case of raw format, just write it and return:
1547                         WriteRawPixelmap(info, frame_id);
1548                     }
1549                     else
1550                     {
1551                         if (IsRenesasDave2D(m_project))
1552                         {
1553                             // force convert the 16 bit with alpha formats to 32 bit argb for Dave2D
1554                             // this should be removed once we only allow compatible formats
1555                             if (m_map->gx_pixelmap_format == GX_COLOR_FORMAT_565RGB &&
1556                                 (m_map->gx_pixelmap_flags & GX_PIXELMAP_ALPHA) &&
1557                                 (info->output_color_format != GX_COLOR_FORMAT_32ARGB) &&
1558                                 (info->output_color_format != GX_COLOR_FORMAT_4444ARGB) &&
1559                                 (info->output_color_format != GX_COLOR_FORMAT_4444BGRA))
1560                             {
1561                                 // If this is 16 bit pixelmap with alpha, convert to 32 bit argb format for Dave2D
1562                                 info->output_color_format = GX_COLOR_FORMAT_32ARGB;
1563                             }
1564                         }
1565 
1566                         WritePixelmapData(info, theme, frame_id);
1567                     }
1568 
1569                     if (info->output_file_enabled)
1570                     {
1571                         m_outfile = outfile_list.GetAt(0);
1572                     }
1573                 }
1574             }
1575         }
1576     }
1577 }
1578 
1579 ////////////////////////////////////////////////////////////////////////////////////////////////
WritePixelmapTable(void)1580 void resource_gen::WritePixelmapTable(void)
1581 {
1582     res_info *info;
1583     CString out;
1584     CCommandInfo *pCmdInfo = GetCmdInfo();
1585     BOOL enabled;
1586     int pixelmap_id;
1587     int frame_id;
1588     CString name;
1589 
1590     WriteComment("Pixelmap Table");
1591 
1592     /* Extern pixelmaps that defined in custom output files. */
1593     for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
1594     {
1595         m_ThemeName = m_project->mDisplays[m_display].themes[theme].theme_name;
1596 
1597         if (pCmdInfo->IsNoGui())
1598         {
1599             enabled = pCmdInfo->IsThemeEnabled(m_ThemeName);
1600         }
1601         else
1602         {
1603             enabled = m_project->mDisplays[m_display].themes[theme].gen_pixelmap_table;
1604         }
1605 
1606         if (!enabled) continue;
1607 
1608         for (pixelmap_id = 1; pixelmap_id < m_pixelmap_dictionary.GetCount(); pixelmap_id++)
1609         {
1610             info = m_project->FindResource(m_display, theme, RES_TYPE_PIXELMAP, m_pixelmap_dictionary.GetAt(pixelmap_id));
1611 
1612             if (IsResEnabled(info) && (info->output_file_enabled) && (!info->binary_mode))
1613             {
1614                 CString theme_name = m_ThemeName;
1615                 int reference_theme = FindResourceReferenceTheme(info, theme);
1616                 if (reference_theme >= 0)
1617                 {
1618                     theme_name = m_project->mDisplays[m_display].themes[reference_theme].theme_name;
1619                 }
1620 
1621                 for (frame_id = 0; frame_id < info->GetPixelmapFrameCount(); frame_id++)
1622                 {
1623                     name = MakePixelmapName(info, frame_id);
1624 
1625                     out.Format(_T("extern GX_CONST GX_PIXELMAP %s_%s_%s_pixelmap;\n"), UpperDisplayName(), theme_name.MakeUpper(), name);
1626                     FileWrite(out);
1627                 }
1628             }
1629         }
1630     }
1631 
1632     FileWrite(CString("\n"));
1633 
1634     /* Write pixelmap table. */
1635     for (int theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
1636     {
1637         m_ThemeName = m_project->mDisplays[m_display].themes[theme].theme_name;
1638 
1639         if (pCmdInfo->IsNoGui())
1640         {
1641             enabled = pCmdInfo->IsThemeEnabled(m_ThemeName);
1642         }
1643         else
1644         {
1645             enabled = m_project->mDisplays[m_display].themes[theme].gen_pixelmap_table;
1646         }
1647 
1648         if (!enabled) continue;
1649 
1650 
1651         CString name = m_project->mDisplays[m_display].name;
1652         name += "_";
1653         name += m_project->mDisplays[m_display].themes[theme].theme_name;
1654         out.Format(_T("GX_CONST GX_PIXELMAP *%s_pixelmap_table[] =\n{\n    GX_NULL"), name);
1655         FileWrite(out);
1656 
1657         for (pixelmap_id = 1; pixelmap_id < m_pixelmap_dictionary.GetCount(); pixelmap_id++)
1658         {
1659             info = m_project->FindResource(m_display, theme, RES_TYPE_PIXELMAP, m_pixelmap_dictionary.GetAt(pixelmap_id));
1660 
1661             if (IsResEnabled(info))
1662             {
1663                 CString theme_name = m_ThemeName;
1664                 int reference_theme = FindResourceReferenceTheme(info, theme);
1665                 if (reference_theme >= 0)
1666                 {
1667                     theme_name = m_project->mDisplays[m_display].themes[reference_theme].theme_name;
1668                 }
1669 
1670                 for (frame_id = 0; frame_id < info->GetPixelmapFrameCount(); frame_id++)
1671                 {
1672                     name = MakePixelmapName(info, frame_id);
1673 
1674                     if (!info->output_file_enabled || !info->binary_mode)
1675                     {
1676                         out.Format(_T(",\n    &%s_%s_%s_pixelmap"), UpperDisplayName(), theme_name.MakeUpper(), name);
1677                         FileWrite(out);
1678                     }
1679                 }
1680             }
1681             else if (IsSystemPixelmap(pixelmap_id))
1682             {
1683                 out.Format(_T(",\n    GX_NULL"));
1684                 FileWrite(out);
1685             }
1686         }
1687 
1688         out.Format(_T("\n};\n"));
1689         FileWrite(out);
1690     }
1691 }
1692 
1693 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteStringDefines(void)1694 void resource_gen::WriteStringDefines(void)
1695 {
1696     CString out;
1697     int string_id;
1698     string_table *pTable = m_project->mDisplays[m_display].stable;
1699     CString display_name = UpperDisplayName();
1700     display_name += "_";
1701     CArray<widget_info*>* info_list;
1702     widget_info* info;
1703     int reference_count;
1704     int output_id = 1;
1705 
1706     if (pTable && pTable->CountStrings() > 0)
1707     {
1708         WriteComment("String Ids");
1709 
1710         for (string_id = 1; string_id < pTable->CountStrings(); string_id++)
1711         {
1712             CString IdName = pTable->GetResourceIdName(string_id);
1713 
1714             if (IdName.IsEmpty())
1715             {
1716                 continue;
1717             }
1718 
1719             info_list = pTable->GetMLViewReferenceWidgetInfoList(IdName);
1720 
1721             if (info_list)
1722             {
1723                 reference_count = info_list->GetCount();
1724             }
1725             else
1726             {
1727                 reference_count = 1;
1728             }
1729 
1730             info = NULL;
1731 
1732             for (int index = 0; index < reference_count; index++)
1733             {
1734                 if (info_list)
1735                 {
1736                     info = info_list->GetAt(index);
1737 
1738                     IdName = pTable->GetResourceIdName(string_id, info);
1739                 }
1740 
1741                 if (m_num_displays > 1)
1742                 {
1743                     out.Format(_T("#define GX_STRING_ID_%s %d\n"), CString(display_name + IdName), output_id);
1744                 }
1745                 else
1746                 {
1747                     out.Format(_T("#define GX_STRING_ID_%s %d\n"), CString(IdName), output_id);
1748                 }
1749 
1750                 output_id++;
1751                 FileWrite(out);
1752             }
1753         }
1754 
1755         out.Format(_T("#define %s_STRING_TABLE_SIZE %d\n"),
1756             UpperDisplayName(), pTable->CountGeneratedStrings());
1757         FileWrite(out);
1758     }
1759 }
1760 
1761 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteStringData(void)1762 void resource_gen::WriteStringData(void)
1763 {
1764     CString out;
1765     int string_id = 1;
1766     int num_strings;
1767     int language = 0;
1768     CString LanguageName;
1769     CString display_name;
1770 
1771     string_table *pTable = m_project->mDisplays[m_display].stable;
1772 
1773     if (!pTable)
1774     {
1775         return;
1776     }
1777 
1778     num_strings = pTable->CountStrings();
1779 
1780     if (num_strings > 0)
1781     {
1782         WriteComment("String values");
1783         display_name = m_project->mDisplays[m_display].name;
1784 
1785         /* Pickup command info class instance. */
1786         CCommandInfo *pCmdInfo = GetCmdInfo();
1787         BOOL enabled;
1788 
1789         for (int language = 0; language < m_project->mHeader.num_languages; language++)
1790         {
1791             LanguageName = m_project->mHeader.languages[language].name;
1792 
1793             if (pCmdInfo->IsNoGui())
1794             {
1795                 enabled = pCmdInfo->IsLanguageEnabled(LanguageName);
1796             }
1797             else
1798             {
1799                 enabled = m_project->mDisplays[m_display].gen_string_table[language];
1800             }
1801 
1802             if (!enabled) continue;
1803 
1804             /* Include string data of enabled languages. */
1805 
1806             for (string_id = 1; string_id < num_strings; string_id++)
1807             {
1808                 WriteOneStringData(display_name, language, string_id);
1809             }
1810         }
1811     }
1812 }
1813 
1814 ////////////////////////////////////////////////////////////////////////////////////////////////
RichTextResIdName2ResId(studiox_project * project,int display,CString & val)1815 CString resource_gen::RichTextResIdName2ResId(studiox_project* project, int display, CString &val)
1816 {
1817     CString out("");
1818     CString tag;
1819     CString id_name;
1820     CString id_prefix;
1821     CString id_val_string;
1822     int res_type;
1823     int res_id;
1824     int index = 0;
1825 
1826     while (1)
1827     {
1828         // Find tag start flag
1829         index = val.Find('<');
1830 
1831         if (index >= 0)
1832         {
1833             out.Append(val.Left(index + 1));
1834             val = val.Mid(index + 1);
1835 
1836             index = val.Find(_T(" "));
1837 
1838             if (index >= 0)
1839             {
1840                 // Get tag
1841                 tag = val.Left(index);
1842 
1843                 if (tag == "f")
1844                 {
1845                     res_type = RES_TYPE_FONT;
1846                     id_prefix = "GX_FONT_ID_";
1847                 }
1848                 else if ((tag == "c") || (tag == "hc"))
1849                 {
1850                     res_type = RES_TYPE_COLOR;
1851                     id_prefix = "GX_COLOR_ID_";
1852                 }
1853                 else
1854                 {
1855                     continue;
1856                 }
1857 
1858                 out.Append(val.Left(index + 1));
1859                 val = val.Mid(index + 1);
1860 
1861                 index = val.Find(_T(">"));
1862                 if (index >= 0)
1863                 {
1864                     // Get resource id name
1865                     id_name = val.Left(index);
1866 
1867                     if (id_name.Find(id_prefix) == 0)
1868                     {
1869                         id_name = id_name.Mid(id_prefix.GetLength());
1870                         res_id = project->GetResourceId(display, res_type, id_name);
1871 
1872                         if (res_id)
1873                         {
1874                             val = val.Mid(index + 1);
1875                             id_val_string.Format(_T("%d>"), res_id);
1876                             out += id_val_string;
1877                         }
1878                     }
1879                 }
1880             }
1881         }
1882         else
1883         {
1884             out.Append(val);
1885             break;
1886         }
1887     }
1888 
1889     return out;
1890 }
1891 
1892 ////////////////////////////////////////////////////////////////////////////////////////////////
MakeUtf8String(studiox_project * project,CString val,int language_index,GX_STRING * out_string,int display,BOOL gen,widget_info * info)1893 void resource_gen::MakeUtf8String(studiox_project* project, CString val, int language_index, GX_STRING *out_string, int display, BOOL gen, widget_info *info)
1894 {
1895     val = RichTextResIdName2ResId(project, display, val);
1896 
1897     // The maximun UTF8 character is 6 bytes, calculate the maximun utf8 buffer size needed for the string.
1898     int max_length = val.GetLength() * 6 + 1;
1899     GX_STRING string;
1900     GX_STRING normalized_text;
1901 
1902     string.gx_string_ptr = new char[max_length];
1903     strcpy_s((char *)string.gx_string_ptr, max_length, CT2A(val.GetString(), CP_UTF8));
1904     string.gx_string_length = strnlen_s(string.gx_string_ptr, max_length);
1905 
1906     if (gx_studio_canonical_normalize((GX_CONST GX_STRING *)&string, &normalized_text) == GX_SUCCESS)
1907     {
1908         delete string.gx_string_ptr;
1909 
1910         string = normalized_text;
1911     }
1912 
1913     if (project->mHeader.languages[language_index].support_bidi_text &&
1914         project->mHeader.languages[language_index].gen_reordered_bidi_text && gen)
1915     {
1916         GX_STRING reordered_bidi_text;
1917 
1918         MakeReorderedBidiText(&string, &reordered_bidi_text, display, info);
1919 
1920         delete string.gx_string_ptr;
1921         string = reordered_bidi_text;
1922     }
1923 
1924     if (project->mHeader.languages[language_index].support_thai_glyph_shaping &&
1925         (!gen || project->mHeader.languages[language_index].gen_adjusted_thai_string))
1926     {
1927 
1928         GX_STRING adjusted_thai_string;
1929         MakeAdjustedThaiString(&string, &adjusted_thai_string);
1930 
1931         if (adjusted_thai_string.gx_string_ptr)
1932         {
1933             delete string.gx_string_ptr;
1934             string = adjusted_thai_string;
1935         }
1936     }
1937 
1938     *out_string = string;
1939 }
1940 
1941 ////////////////////////////////////////////////////////////////////////////////////////////////
GetMlTextDisplayInfo(widget_info * info,int * font_id,GX_VALUE * display_width)1942 bool resource_gen::GetMlTextDisplayInfo(widget_info *info, int* font_id, GX_VALUE* display_width)
1943 {
1944     if (info && (info->basetype == GX_TYPE_MULTI_LINE_TEXT_VIEW))
1945     {
1946         // Calculate display width
1947         GX_WIDGET widget;
1948         GX_RECTANGLE client;
1949         INT width;
1950 
1951         widget.gx_widget_style = info->style;
1952         widget.gx_widget_size = info->size;
1953         gx_widget_client_get(&widget, -1, &client);
1954 
1955         width = client.gx_rectangle_right - client.gx_rectangle_left + 1;
1956         width = width - (info->ewi.text_info.whitespace << 1) - 3;
1957 
1958         // Retrieve font
1959         *font_id = info->font_id[NORMAL_FONT_INDEX];
1960 
1961         widget_info *child = info->GetChildWidgetInfo();
1962 
1963         while (child)
1964         {
1965             if (child->basetype == GX_TYPE_VERTICAL_SCROLL)
1966             {
1967                 width -= (child->size.gx_rectangle_right - child->size.gx_rectangle_left + 1);
1968                 break;
1969             }
1970 
1971             child = child->GetNextWidgetInfo();
1972         }
1973 
1974         *display_width = (GX_VALUE)width;
1975         return TRUE;
1976     }
1977 
1978     return FALSE;
1979 }
1980 
1981 ////////////////////////////////////////////////////////////////////////////////////////////////
MakeReorderedBidiText(GX_STRING * utf8str,GX_STRING * out_string,int display,widget_info * info)1982 void resource_gen::MakeReorderedBidiText(GX_STRING *utf8str, GX_STRING *out_string, int display, widget_info *info)
1983 {
1984     //generate bidi text in display order
1985     GX_BIDI_TEXT_INFO input_info;
1986     GX_BIDI_RESOLVED_TEXT_INFO *resolved_info;
1987     char *reordered_bidi_text = GX_NULL;
1988     UINT  reordered_index = 0;
1989     GX_VALUE display_width;
1990     int font_id;
1991 
1992     memset(&input_info, 0, sizeof(GX_BIDI_TEXT_INFO));
1993 
1994     if (GetMlTextDisplayInfo(info, &font_id, &display_width))
1995     {
1996         studiox_project* project = GetOpenProject();
1997         res_info* info = project->FindResource(display, 0, RES_TYPE_FONT, font_id);
1998 
1999         if (info)
2000         {
2001             input_info.gx_bidi_text_info_display_width = display_width;
2002             input_info.gx_bidi_text_info_font = info->font;
2003         }
2004     }
2005 
2006     input_info.gx_bidi_text_info_text = *utf8str;
2007 
2008     if (_gx_utility_bidi_paragraph_reorder(&input_info, &resolved_info) == GX_SUCCESS)
2009     {
2010         int buffer_size = 0;
2011         UINT index;
2012         GX_BIDI_RESOLVED_TEXT_INFO* next = resolved_info;
2013         GX_STRING* line_string;
2014 
2015         // Calculate buffer size needed for loading the reordered bidi text.
2016         while (next)
2017         {
2018             for (index = 0; index < next->gx_bidi_resolved_text_info_total_lines; index++)
2019             {
2020                 if (next->gx_bidi_resolved_text_info_text)
2021                 {
2022                     buffer_size += next->gx_bidi_resolved_text_info_text[index].gx_string_length;
2023                 }
2024 
2025                 buffer_size++;
2026             }
2027             next = next->gx_bidi_resolved_text_info_next;
2028         }
2029 
2030         buffer_size++;
2031         reordered_bidi_text = new char[buffer_size];
2032 
2033         next = resolved_info;
2034 
2035         GX_BOOL insert_line_break = GX_FALSE;
2036 
2037         // Copy reordered bidi text to the buffer.
2038         while (next)
2039         {
2040             for (index = 0; index < next->gx_bidi_resolved_text_info_total_lines; index++)
2041             {
2042                 if (next->gx_bidi_resolved_text_info_text)
2043                 {
2044                     line_string = &next->gx_bidi_resolved_text_info_text[index];
2045                     memcpy_s(reordered_bidi_text + reordered_index, buffer_size - reordered_index, line_string->gx_string_ptr, line_string->gx_string_length);
2046                     reordered_index += line_string->gx_string_length;
2047                 }
2048 
2049                 if ((index < next->gx_bidi_resolved_text_info_total_lines - 1) ||
2050                     (next->gx_bidi_resolved_text_info_next))
2051                 {
2052                     reordered_bidi_text[reordered_index++] = GX_KEY_CARRIAGE_RETURN;
2053                 }
2054             }
2055             next = next->gx_bidi_resolved_text_info_next;
2056         }
2057 
2058         reordered_bidi_text[reordered_index] = '\0';
2059 
2060         _gx_utility_bidi_resolved_text_info_delete(&resolved_info);
2061     }
2062 
2063     out_string->gx_string_ptr = reordered_bidi_text;
2064     out_string->gx_string_length = reordered_index;
2065 }
2066 
2067 ////////////////////////////////////////////////////////////////////////////////////////////////
MakeAdjustedThaiString(GX_STRING * utf8str,GX_STRING * out_string)2068 void resource_gen::MakeAdjustedThaiString(GX_STRING *utf8str, GX_STRING *out_string)
2069 {
2070     ULONG *code_list;
2071     UINT code_count;
2072     UINT index;
2073     GX_CHAR *adjusted_string;
2074     UINT     count;
2075     UINT     glyph_len;
2076 
2077     out_string->gx_string_ptr = GX_NULL;
2078     out_string->gx_string_length = 0;
2079 
2080     if (_gx_utility_thai_glyph_shaping(utf8str, &code_list, &code_count) == GX_SUCCESS)
2081     {
2082         adjusted_string = new GX_CHAR[code_count * 6 + 1];
2083         count = 0;
2084 
2085         for (index = 0; index < code_count; index++)
2086         {
2087             _gx_utility_unicode_to_utf8(code_list[index], (GX_UBYTE *)(adjusted_string + count), &glyph_len);
2088             count += glyph_len;
2089         }
2090 
2091         _gx_system_memory_free(code_list);
2092         adjusted_string[count] = '\0';
2093 
2094         out_string->gx_string_ptr = adjusted_string;
2095         out_string->gx_string_length = count;
2096     }
2097 }
2098 
2099 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteOneStringData(CString & display_name,int language_index,int string_id)2100 void resource_gen::WriteOneStringData(CString &display_name, int language_index, int string_id)
2101 {
2102     CString out;
2103     GX_STRING utf8str;
2104     GX_CONST GX_CHAR *data;
2105     unsigned char  byte;
2106     BOOL  HasMultiByte = FALSE;
2107 
2108     string_table* pTable = m_project->mDisplays[m_display].stable;
2109 
2110     CString id_name = pTable->GetResourceIdName(string_id);
2111 
2112     if (id_name.IsEmpty())
2113     {
2114         return;
2115     }
2116     CString val = pTable->GetString(id_name, language_index);
2117 
2118     if (val.IsEmpty())
2119     {
2120         return;
2121     }
2122 
2123     CArray<widget_info*> *info_list = pTable->GetMLViewReferenceWidgetInfoList(id_name);
2124 
2125     int reference_count = 1;
2126 
2127     if (info_list)
2128     {
2129         reference_count = info_list->GetCount();
2130     }
2131 
2132     widget_info *info = NULL;
2133 
2134     for (int index = 0; index < reference_count; index++)
2135     {
2136         if (info_list)
2137         {
2138             info = info_list->GetAt(index);
2139             id_name = pTable->GetResourceIdName(string_id, info);
2140         }
2141 
2142         MakeUtf8String(m_project, val, language_index, &utf8str, m_display, TRUE, info);
2143 
2144         data = utf8str.gx_string_ptr;
2145 
2146         while (*data)
2147         {
2148             byte = *data++;
2149             if (byte & 0x80)
2150             {
2151                 HasMultiByte = TRUE;
2152                 break;
2153             }
2154         }
2155 
2156         CString language_name = m_project->mHeader.languages[language_index].name;
2157         language_name.Replace(' ', '_');
2158 
2159         if (HasMultiByte)
2160         {
2161             out.Format(_T("GX_CONST GX_UBYTE %s_%s_%s[] = {"), display_name, id_name, language_name);
2162             FileWrite(out);
2163 
2164             data = utf8str.gx_string_ptr;
2165 
2166             while (*data)
2167             {
2168                 byte = *data++;
2169                 out.Format(_T("0x%02x, "), byte);
2170                 FileWrite(out);
2171             }
2172             FileWrite(CString("0x00};\n"));
2173         }
2174         else
2175         {
2176             val = utf8str.gx_string_ptr;
2177             val.Replace(_T("\\"), _T("\\\\"));
2178             val.Replace(_T("\""), _T("\\\""));
2179             val.Replace(_T("\'"), _T("\\\'"));
2180             val.Replace(_T("\n"), _T("\\n"));
2181             val.Replace(_T("\r"), _T("\\r"));
2182 
2183             out.Format(_T("GX_CONST GX_UBYTE %s_%s_%s[] = \"%s\";\n"), display_name, id_name, language_name, val);
2184 
2185             FileWrite(out);
2186         }
2187 
2188         delete utf8str.gx_string_ptr;
2189     }
2190 }
2191 
2192 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteStringTable(void)2193 void resource_gen::WriteStringTable(void)
2194 {
2195     CString out;
2196     int string_id = 1;
2197     int num_strings;
2198     int language = 0;
2199     CString LanguageName;
2200     CString display_name;
2201     CString val;
2202 
2203     string_table *pTable = m_project->mDisplays[m_display].stable;
2204 
2205     if (!pTable)
2206     {
2207         return;
2208     }
2209 
2210     num_strings = pTable->CountStrings();
2211 
2212     if (num_strings > 0)
2213     {
2214         display_name = m_project->mDisplays[m_display].name;
2215 
2216         /* Pickup command info class instance. */
2217         CCommandInfo *pCmdInfo = GetCmdInfo();
2218         BOOL enabled;
2219         INT language_count = 0;
2220 
2221         for (int language = 0; language < m_project->mHeader.num_languages; language++)
2222         {
2223             LanguageName = m_project->mHeader.languages[language].name;
2224 
2225             if (pCmdInfo->IsNoGui())
2226             {
2227                 enabled = pCmdInfo->IsLanguageEnabled(LanguageName);
2228             }
2229             else
2230             {
2231                 enabled = m_project->mDisplays[m_display].gen_string_table[language];
2232             }
2233 
2234             if (!enabled) continue;
2235 
2236             out.Format(_T("\n/* String Table for %s language %s */\n\n"), display_name, LanguageName);
2237             FileWrite(out);
2238 
2239             LanguageName.Replace(' ', '_');
2240             if(project_lib_version() >= GX_VERSION_STRING_LENGTH_FIX)
2241             {
2242                 WriteOneStringTableExt(display_name, LanguageName, language, pTable, num_strings);
2243             }
2244             else
2245             {
2246                 WriteOneStringTable(display_name, LanguageName, language, pTable, num_strings);
2247             }
2248 
2249             /* Output string table of enabled languages. */
2250 
2251             language_count++;
2252         }
2253 
2254         // now write the language table
2255 
2256         WriteComment(" Language Table ");
2257 
2258         if (language_count)
2259         {
2260             if (project_lib_version() >= GX_VERSION_STRING_LENGTH_FIX)
2261             {
2262                 WriteLanguageTableExt(display_name, language_count);
2263             }
2264             else
2265             {
2266                 WriteLanguageTable(display_name, language_count);
2267             }
2268 
2269             if (string_table::TestGenerateLanguageDirectionTable())
2270             {
2271                 WriteComment(" Language Direction Table ");
2272 
2273                 WriteLanguageDirectionTable(display_name, language_count);
2274             }
2275         }
2276     }
2277 }
2278 
2279 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteLanguageTable(CString display_name,INT language_count)2280 void resource_gen::WriteLanguageTable(CString display_name, INT language_count)
2281 {
2282     CString out;
2283     CString LanguageName;
2284     CCommandInfo* pCmdInfo = GetCmdInfo();
2285     BOOL enabled;
2286 
2287     out.Format(_T("\nGX_CONST GX_UBYTE **%s_language_table[%d] = \n{\n"), m_project->mDisplays[m_display].name, language_count);
2288 
2289     FileWrite(out);
2290 
2291     for (int language = 0; language < m_project->mHeader.num_languages; language++)
2292     {
2293         LanguageName = m_project->mHeader.languages[language].name;
2294 
2295         if (pCmdInfo->IsNoGui())
2296         {
2297             enabled = pCmdInfo->IsLanguageEnabled(LanguageName);
2298         }
2299         else
2300         {
2301             enabled = m_project->mDisplays[m_display].gen_string_table[language];
2302         }
2303 
2304         if (!enabled) continue;
2305 
2306         /* Output language table with enabled string tables. */
2307         LanguageName.Replace(' ', '_');
2308         out.Format(_T("    %s_%s_string_table,\n"), display_name, LanguageName);
2309 
2310         FileWrite(out);
2311     }
2312     FileWrite(CString("};\n"));
2313 }
2314 
2315 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteLanguageTableExt(CString display_name,INT language_count)2316 void resource_gen::WriteLanguageTableExt(CString display_name, INT language_count)
2317 {
2318     CString out;
2319     CString LanguageName;
2320     CCommandInfo* pCmdInfo = GetCmdInfo();
2321     BOOL enabled;
2322 
2323     out.Format(_T("\nGX_CONST GX_STRING *%s_language_table[%d] = \n{\n"), m_project->mDisplays[m_display].name, language_count);
2324 
2325     FileWrite(out);
2326 
2327     for (int language = 0; language < m_project->mHeader.num_languages; language++)
2328     {
2329         LanguageName = m_project->mHeader.languages[language].name;
2330 
2331         if (pCmdInfo->IsNoGui())
2332         {
2333             enabled = pCmdInfo->IsLanguageEnabled(LanguageName);
2334         }
2335         else
2336         {
2337             enabled = m_project->mDisplays[m_display].gen_string_table[language];
2338         }
2339 
2340         if (!enabled) continue;
2341 
2342         /* Output language table with enabled string tables. */
2343         LanguageName.Replace(' ', '_');
2344         out.Format(_T("    %s_%s_string_table,\n"), display_name, LanguageName);
2345 
2346         FileWrite(out);
2347     }
2348     FileWrite(CString("};\n"));
2349 }
2350 
2351 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteLanguageDirectionTable(CString display_name,INT language_count)2352 void resource_gen::WriteLanguageDirectionTable(CString display_name, INT language_count)
2353 {
2354     CString out;
2355 
2356     out.Format(_T("\nGX_CONST GX_UBYTE %s_language_direction_table[%d] = \n{\n"), m_project->mDisplays[m_display].name, language_count);
2357 
2358     FileWrite(out);
2359 
2360     for (int language = 0; language < m_project->mHeader.num_languages; language++)
2361     {
2362         if (string_table::IsRight2LeftLanguage(language))
2363         {
2364             out = L"    GX_LANGUAGE_DIRECTION_RTL";
2365         }
2366         else
2367         {
2368             out = L"    GX_LANGUAGE_DIRECTION_LTR";
2369         }
2370 
2371         FileWrite(out);
2372 
2373         if (language == m_project->mHeader.num_languages - 1)
2374         {
2375             out = L"\n";
2376         }
2377         else
2378         {
2379             out = L",\n";
2380         }
2381 
2382         FileWrite(out);
2383     }
2384     FileWrite(CString("};\n"));
2385 }
2386 
2387 
2388 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteOneStringTable(CString & display_name,CString & language_name,int language_index,string_table * string_table,int num_strings)2389 void resource_gen::WriteOneStringTable(CString &display_name, CString &language_name, int language_index,
2390                                        string_table* string_table, int num_strings)
2391 {
2392         CString out;
2393         CString val;
2394         int string_id;
2395         CString id_name;
2396 
2397         out.Format(_T("GX_CONST GX_UBYTE *%s_%s_string_table[%d] =\n{\n    GX_NULL,\n"),
2398             display_name, language_name, num_strings);
2399         FileWrite(out);
2400 
2401         for (string_id = 1; string_id < num_strings; string_id++)
2402         {
2403             id_name = string_table->GetResourceIdName(string_id);
2404 
2405             if (id_name.IsEmpty())
2406             {
2407                 continue;
2408             }
2409 
2410 
2411             val = string_table->GetString(id_name, language_index);
2412 
2413             if (val.IsEmpty())
2414             {
2415                 if (string_id < num_strings - 1)
2416                 {
2417                     out.Format(_T("    GX_NULL,\n"));
2418                 }
2419                 else
2420                 {
2421                     out.Format(_T("    GX_NULL\n"));
2422                 }
2423             }
2424             else
2425             {
2426                 if (string_id < num_strings - 1)
2427                 {
2428                     out.Format(_T("    %s_%s_%s,\n"), display_name, id_name, language_name);
2429                 }
2430                 else
2431                 {
2432                     out.Format(_T("    %s_%s_%s\n"), display_name, id_name, language_name);
2433                 }
2434             }
2435             FileWrite(out);
2436         }
2437         out.Format(_T("\n};\n"));
2438         FileWrite(out);
2439 }
2440 
2441 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteOneStringTableExt(CString & display_name,CString & language_name,int language_index,string_table * string_table,int num_strings)2442 void resource_gen::WriteOneStringTableExt(CString &display_name, CString &language_name, int language_index,
2443                                                        string_table* string_table, int num_strings)
2444 {
2445     CString out;
2446     CString val;
2447     int string_id;
2448     CString id_name;
2449 
2450     out.Format(_T("GX_CONST GX_STRING %s_%s_string_table[%d] =\n{\n    {GX_NULL, 0},\n"),
2451         display_name, language_name, string_table->CountGeneratedStrings());
2452     FileWrite(out);
2453 
2454     CArray<widget_info *> *info_list;
2455     int reference_count;
2456     widget_info *info;
2457 
2458     for (string_id = 1; string_id < num_strings; string_id++)
2459     {
2460         id_name = string_table->GetResourceIdName(string_id);
2461 
2462         if (id_name.IsEmpty())
2463         {
2464             continue;
2465         }
2466 
2467         val = string_table->GetString(id_name, language_index);
2468 
2469         info_list = string_table->GetMLViewReferenceWidgetInfoList(id_name);
2470         info = NULL;
2471         reference_count = 1;
2472 
2473         if (info_list)
2474         {
2475             reference_count = info_list->GetCount();
2476         }
2477 
2478         for (int index = 0; index < reference_count; index++)
2479         {
2480 
2481             if (info_list)
2482             {
2483                 info = info_list->GetAt(index);
2484                 id_name = string_table->GetResourceIdName(string_id, info);
2485             }
2486 
2487             if (val.IsEmpty())
2488             {
2489                 if (string_id < num_strings - 1)
2490                 {
2491                     out.Format(_T("    {GX_NULL, 0},\n"));
2492                 }
2493                 else
2494                 {
2495                     out.Format(_T("    {GX_NULL, 0}\n"));
2496                 }
2497             }
2498             else
2499             {
2500 
2501                 if (string_id < num_strings - 1)
2502                 {
2503                     out.Format(_T("    {(GX_CONST GX_CHAR *)%s_%s_%s, sizeof(%s_%s_%s) - 1},\n"),
2504                         display_name, id_name, language_name,
2505                         display_name, id_name, language_name);
2506                 }
2507                 else
2508                 {
2509                     out.Format(_T("    {(GX_CONST GX_CHAR *)%s_%s_%s, sizeof(%s_%s_%s) - 1}\n"),
2510                         display_name, id_name, language_name,
2511                         display_name, id_name, language_name);
2512                 }
2513             }
2514             FileWrite(out);
2515         }
2516     }
2517     out.Format(_T("};\n"));
2518     FileWrite(out);
2519 }
2520 
WriteScrollbarAppearance(GX_SCROLLBAR_APPEARANCE & appear)2521 void resource_gen::WriteScrollbarAppearance(GX_SCROLLBAR_APPEARANCE &appear)
2522 {
2523     CString out;
2524 
2525     if (project_lib_version() >= 50302)
2526     {
2527         out.Format(_T("")
2528             _T("    {\n")
2529             _T("        %d, /* scroll width */\n")
2530             _T("        %d, /* thumb width  */\n")
2531             _T("        %d, /* thumb travel min */\n")
2532             _T("        %d, /* thumb travel max */\n")
2533             _T("        %d, /* thumb border style */\n")
2534             _T("        %s, /* scroll fill pixelmap */\n")
2535             _T("        %s, /* scroll thumb pixelmap */\n")
2536             _T("        %s, /* scroll up pixelmap */\n")
2537             _T("        %s, /* scroll down pixelmap */\n")
2538             _T("        %s, /* scroll thumb color */\n")
2539             _T("        %s, /* scroll thumb border color */\n")
2540             _T("        %s, /* scroll button color */\n")
2541             _T("    },\n"),
2542             appear.gx_scroll_width,
2543             appear.gx_scroll_thumb_width,
2544             appear.gx_scroll_thumb_travel_min,
2545             appear.gx_scroll_thumb_travel_max,
2546             appear.gx_scroll_thumb_border_style,
2547             screen_generator::GetPixelmapIdName(m_project, m_display, appear.gx_scroll_fill_pixelmap),
2548             screen_generator::GetPixelmapIdName(m_project, m_display, appear.gx_scroll_thumb_pixelmap),
2549             screen_generator::GetPixelmapIdName(m_project, m_display, appear.gx_scroll_up_pixelmap),
2550             screen_generator::GetPixelmapIdName(m_project, m_display, appear.gx_scroll_down_pixelmap),
2551             screen_generator::GetColorIdName(m_project, m_display, appear.gx_scroll_thumb_color),
2552             screen_generator::GetColorIdName(m_project, m_display, appear.gx_scroll_thumb_border_color),
2553             screen_generator::GetColorIdName(m_project, m_display, appear.gx_scroll_button_color));
2554     }
2555     else
2556     {
2557         out.Format(_T("")
2558             _T("    {\n")
2559             _T("        %d, /* scroll width */\n")
2560             _T("        %d, /* thumb width  */\n")
2561             _T("        %d, /* thumb travel min */\n")
2562             _T("        %d, /* thumb travel max */\n")
2563             _T("        %s, /* scroll fill pixelmap */\n")
2564             _T("        %s, /* scroll thumb pixelmap */\n")
2565             _T("        %s, /* scroll up pixelmap */\n")
2566             _T("        %s, /* scroll down pixelmap */\n")
2567             _T("        %s, /* scroll fill color */\n")
2568             _T("        %s, /* scroll button color */\n")
2569             _T("    },\n"),
2570             appear.gx_scroll_width,
2571             appear.gx_scroll_thumb_width,
2572             appear.gx_scroll_thumb_travel_min,
2573             appear.gx_scroll_thumb_travel_max,
2574             screen_generator::GetPixelmapIdName(m_project, m_display, appear.gx_scroll_fill_pixelmap),
2575             screen_generator::GetPixelmapIdName(m_project, m_display, appear.gx_scroll_thumb_pixelmap),
2576             screen_generator::GetPixelmapIdName(m_project, m_display, appear.gx_scroll_up_pixelmap),
2577             screen_generator::GetPixelmapIdName(m_project, m_display, appear.gx_scroll_down_pixelmap),
2578             _T("GX_COLOR_ID_SCROLL_FILL"),
2579             screen_generator::GetColorIdName(m_project, m_display, appear.gx_scroll_button_color));
2580     }
2581     FileWrite(out);
2582 }
2583 
2584 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteThemes(void)2585 void resource_gen::WriteThemes(void)
2586 {
2587 
2588     int theme;
2589     int theme_count = 0;
2590     CString out;
2591     CString name;
2592     BOOL  enabled;
2593     CString color_table_name("GX_NULL");
2594     CString font_table_name("GX_NULL");
2595     CString pixelmap_table_name("GX_NULL");
2596 
2597     CCommandInfo *pCmdInfo = GetCmdInfo();
2598 
2599     for (theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
2600     {
2601         if (pCmdInfo->IsNoGui())
2602         {
2603             enabled = pCmdInfo->IsThemeEnabled(m_project->mDisplays[m_display].themes[theme].theme_name);
2604         }
2605         else
2606         {
2607             enabled = m_project->mDisplays[m_display].themes[theme].enabled;
2608         }
2609 
2610         if (!enabled) continue;
2611 
2612         theme_count++;
2613 
2614         name = m_project->mDisplays[m_display].name;
2615         name += "_";
2616         name += m_project->mDisplays[m_display].themes[theme].theme_name;
2617 
2618         if (m_project->mDisplays[m_display].themes[theme].gen_color_table || pCmdInfo->IsNoGui())
2619         {
2620             color_table_name.Format(_T("%s_color_table"), name);
2621         }
2622 
2623         if (m_project->mDisplays[m_display].themes[theme].gen_font_table || pCmdInfo->IsNoGui())
2624         {
2625             font_table_name.Format(_T("%s_font_table"), name);
2626         }
2627 
2628         if (m_project->mDisplays[m_display].themes[theme].gen_pixelmap_table || pCmdInfo->IsNoGui())
2629         {
2630             pixelmap_table_name.Format(_T("%s_pixelmap_table"), name);
2631         }
2632 
2633         out.Format(_T("\nGX_THEME %s =\n")
2634             _T("{\n")
2635             _T("    (GX_COLOR *) %s,\n")
2636             _T("    (GX_FONT **) %s,\n")
2637             _T("    (GX_PIXELMAP **) %s,\n"),
2638             name, color_table_name, font_table_name, pixelmap_table_name);
2639         FileWrite(out);
2640 
2641         if (m_project->mDisplays[m_display].colorformat == GX_COLOR_FORMAT_8BIT_PALETTE &&
2642             m_project->mDisplays[m_display].themes[theme].palette != NULL)
2643         {
2644             out.Format(_T("    (GX_COLOR *) %s_palette,\n"), name);
2645         }
2646         else
2647         {
2648             out.Format(_T("    NULL,\n"));
2649         }
2650         FileWrite(out);
2651 
2652         WriteScrollbarAppearance(m_project->mDisplays[m_display].themes[theme].VScrollAppearance);
2653         WriteScrollbarAppearance(m_project->mDisplays[m_display].themes[theme].HScrollAppearance);
2654         out.Empty();
2655         screen_generator::AddScrollbarStyles(m_project->mDisplays[m_display].themes[theme].VScrollStyle, out);
2656         out.TrimLeft('|');
2657         out = CString(_T("    ")) + out + _T(",\n");
2658         FileWrite(out);
2659 
2660         out.Empty();
2661         screen_generator::AddScrollbarStyles(m_project->mDisplays[m_display].themes[theme].HScrollStyle, out);
2662         out.TrimLeft('|');
2663         out = CString(_T("    ")) + out + _T(",\n");
2664         FileWrite(out);
2665         out.Format(_T("    %d, /* color table size */\n"), m_color_table_size);
2666         FileWrite(out);
2667         out.Format(_T("    %d, /* font table size */\n"), m_font_table_size);
2668         FileWrite(out);
2669         out.Format(_T("    %d, /* pixelmap table size */\n"), m_pixelmap_table_size);
2670         FileWrite(out);
2671         if (m_project->mDisplays[m_display].colorformat == GX_COLOR_FORMAT_8BIT_PALETTE &&
2672             m_project->mDisplays[m_display].themes[theme].palette != NULL)
2673         {
2674             /* Only 8bit palette size is wanted to be generated.
2675                4bpp driver contains palette table. But it is just used inside Studio.*/
2676             out.Format(_T("    %d  /* palette size */\n"), m_project->mDisplays[m_display].themes[theme].palette_total_size);
2677 
2678         }
2679         else
2680         {
2681             out.Format(_T("    %d  /* palette size */\n"), 0);
2682         }
2683         FileWrite(out);
2684         FileWrite(CString("\n};\n"));
2685     }
2686 
2687     if (theme_count)
2688     {
2689         out.Format(_T("GX_CONST GX_THEME *%s_theme_table[%d] =\n{\n"),
2690             m_project->mDisplays[m_display].name,
2691             theme_count);
2692         FileWrite(out);
2693         INT count = 0;
2694 
2695         for (theme = 0; theme < m_project->mDisplays[m_display].num_themes; theme++)
2696         {
2697             if (pCmdInfo->IsNoGui())
2698             {
2699                 enabled = pCmdInfo->IsThemeEnabled(m_project->mDisplays[m_display].themes[theme].theme_name);
2700             }
2701             else
2702             {
2703                 enabled = m_project->mDisplays[m_display].themes[theme].enabled;
2704             }
2705 
2706             if (!enabled) continue;
2707 
2708             count++;
2709 
2710             name = m_project->mDisplays[m_display].name;
2711             name += "_";
2712             name += m_project->mDisplays[m_display].themes[theme].theme_name;
2713             if (count < theme_count)
2714             {
2715                 out.Format(_T("    &%s,\n"), name);
2716             }
2717             else
2718             {
2719                 out.Format(_T("    &%s\n"), name);
2720             }
2721             FileWrite(out);
2722         }
2723         FileWrite(CString("};\n\n"));
2724     }
2725 }
2726 
2727 ////////////////////////////////////////////////////////////////////////////////////////////////
GetPageHead(res_info * info,int theme_id,int font_id)2728 GX_FONT *resource_gen::GetPageHead(res_info* info, int theme_id, int font_id)
2729 {
2730     GX_FONT* head_page = NULL;
2731 
2732     if (!info->pathinfo.pathname.IsEmpty())
2733     {
2734         head_page = m_optimized_fonts[theme_id].GetAt(font_id);
2735 
2736         if (!head_page)
2737         {
2738             /* KGM Make the font again, with optimization, and write out the optimized version */
2739             /* Don't forget to delete the temporary font */
2740 
2741             head_page = MakeOptimizedFont(info, m_display, m_warn_on_error);
2742 
2743             if (head_page)
2744             {
2745                 m_optimized_fonts[theme_id].SetAt(font_id, head_page);
2746             }
2747             else
2748             {
2749                 // Only generate error once.
2750                 m_warn_on_error = FALSE;
2751             }
2752         }
2753     }
2754     else
2755     {
2756         // Rotation angle is set, need to rotate default system font.
2757         switch (info->font_bits)
2758         {
2759         case 8:
2760             head_page = &_gx_system_font_8bpp;
2761             break;
2762 
2763         case 4:
2764             if (IsDave2dFontFormat(m_project, m_display))
2765             {
2766                 head_page = &_gx_dave2d_system_font_4bpp;
2767             }
2768             else
2769             {
2770                 head_page = &_gx_system_font_4bpp;
2771             }
2772             break;
2773 
2774         case 1:
2775             if (IsDave2dFontFormat(m_project, m_display))
2776             {
2777                 head_page = &_gx_dave2d_system_font_mono;
2778             }
2779             else
2780             {
2781                 head_page = &_gx_system_font_mono;
2782             }
2783             break;
2784 
2785         default:
2786             // Do nothing.
2787             break;
2788         }
2789     }
2790 
2791     return head_page;
2792 }
2793 
2794 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteFont(res_info * info,int theme_id,int font_id)2795 void resource_gen::WriteFont(res_info *info, int theme_id, int font_id)
2796 {
2797     int pagecount = 1;
2798     int pageindex;
2799     GX_FONT *head_page = GetPageHead(info, theme_id, font_id);
2800     BOOL IsLast = TRUE;
2801 
2802     if (!head_page)
2803     {
2804         CString msg;
2805         msg.Format(_T("Unable to create font: %s using pathname: %s"), info->name, info->pathinfo.pathname);
2806         ErrorMsg(msg);
2807         return;
2808     }
2809 
2810     // write the pages out in reverse order, so that we can link them together without
2811     // first declaring them.
2812 
2813     const GX_FONT *font_page = head_page;
2814 
2815     while(font_page->gx_font_next_page)
2816     {
2817         font_page = font_page->gx_font_next_page;
2818         pagecount++;
2819     }
2820 
2821     CString name;
2822 
2823     while(pagecount)
2824     {
2825         font_page = head_page;
2826         for (pageindex = 1; pageindex < pagecount; pageindex++)
2827         {
2828             font_page = font_page->gx_font_next_page;
2829         }
2830 
2831         name.Format(_T("%s_%s"), m_ThemeName.MakeUpper(), info->name);
2832 
2833         WriteFontPage(font_page, name, pagecount, IsLast, info->output_file_enabled);
2834         pagecount--;
2835         IsLast = FALSE;
2836     }
2837 }
2838 
2839 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteKerningTable(GX_UBYTE * kerning_table,CString & name,GX_CHAR_CODE charval)2840 void resource_gen::WriteKerningTable(GX_UBYTE *kerning_table, CString &name, GX_CHAR_CODE charval)
2841 {
2842     GX_UBYTE *data;
2843     CString out;
2844     CString val;
2845     BOOL written = TRUE;
2846     int table_size;
2847     GX_UBYTE pair_counts = *kerning_table;
2848 
2849     /* Add pair counts and kerning value size. */
2850     table_size = sizeof(GX_UBYTE) + pair_counts * (sizeof(GX_CHAR) + sizeof(GX_UBYTE));
2851 
2852     /* Write kerning table */
2853     out.Format(_T("static GX_CONST GX_UBYTE FONT_%s_char_%2x_kerning_table[%u] =\n{\n"), name, charval, table_size);
2854     FileWrite(out);
2855     out = CString("    ");
2856 
2857     data = kerning_table;
2858     for (int i = 0; i < table_size; i++)
2859     {
2860         val.Format(_T("0x%02x"), *data);
2861         out += val;
2862         if (i != (table_size - 1))
2863         {
2864             out += ", ";
2865         }
2866         written = CheckLineFeed(out);
2867         data++;
2868     }
2869     if (!written)
2870     {
2871         FileWrite(out);
2872     }
2873     out = CString("\n};\n");
2874     FileWrite(out);
2875 }
2876 
2877 ////////////////////////////////////////////////////////////////////////////////////////////////
Rotate8bitGlyphData(GX_CONST GX_UBYTE * map,INT width,INT height)2878 GX_UBYTE *resource_gen::Rotate8bitGlyphData(GX_CONST GX_UBYTE* map, INT width, INT height)
2879 {
2880     int rotated_width = height;
2881     int rotated_height = width;
2882     int data_size = rotated_width * rotated_height;
2883     int putsign;
2884 
2885     if (!data_size)
2886     {
2887         return NULL;
2888     }
2889 
2890     GX_UBYTE* data = new GX_UBYTE[data_size];
2891     GX_UBYTE* putrow = data;
2892     GX_UBYTE* put;
2893     GX_CONST GX_UBYTE* get = map;
2894 
2895     if (m_project->mDisplays[m_display].rotation_angle == GX_SCREEN_ROTATION_CW)
2896     {
2897         /* Write row from top to bottom to colum from left to right. */
2898         putrow += (rotated_height - 1) * rotated_width;
2899         putsign = 1;
2900     }
2901     else
2902     {
2903         // CCW
2904         putrow += (rotated_width - 1);
2905         putsign = -1;
2906     }
2907 
2908     for (int h = 0; h < height; h++)
2909     {
2910         put = putrow;
2911 
2912         for (int w = 0; w < width; w++)
2913         {
2914             *put = *get;
2915             get++;
2916             put -= rotated_width * putsign;
2917         }
2918 
2919         putrow += putsign;
2920     }
2921 
2922     return data;
2923 }
2924 
2925 ////////////////////////////////////////////////////////////////////////////////////////////////
Rotate4bitGlyphData(GX_CONST GX_UBYTE * map,INT width,INT height)2926 GX_UBYTE* resource_gen::Rotate4bitGlyphData(GX_CONST GX_UBYTE* map, INT width, INT height)
2927 {
2928     int datasize;
2929     int rotated_width = height;
2930     int rotated_height = width;
2931     GX_UBYTE* data;
2932     GX_UBYTE* putrow;
2933     GX_UBYTE* put;
2934     int       putstride;
2935     int       putsign;
2936     GX_CONST GX_UBYTE* getrow;
2937     GX_CONST GX_UBYTE* get;
2938     int                getstride;
2939     GX_UBYTE pixel;
2940 
2941     putstride = GetRowPitch(rotated_width, 4);
2942     datasize = putstride * rotated_height;
2943     data = new GX_UBYTE[datasize];
2944     putrow = data;
2945 
2946     getstride = GetRowPitch(width, 4);
2947     getrow = map;
2948 
2949     if (m_project->mDisplays[m_display].rotation_angle == GX_SCREEN_ROTATION_CW)
2950     {
2951         /* Write row from top to bottom to colum from left to right. */
2952         putrow += (rotated_height - 1) * putstride;
2953         putsign = 1;
2954     }
2955     else
2956     {
2957         getrow += (height - 1) * getstride;
2958         putsign = -1;
2959     }
2960 
2961     for (int h = 0; h < height; h++)
2962     {
2963         put = putrow;
2964         get = getrow;
2965 
2966         for (int w = 0; w < width; w++)
2967         {
2968             if (w & 1)
2969             {
2970                 if (IsDave2dFontFormat(m_project, m_display))
2971                 {
2972                     pixel = (*get) & 0xf0;
2973                 }
2974                 else
2975                 {
2976                     pixel = ((*get) << 4);
2977                 }
2978 
2979                 get++;
2980             }
2981             else
2982             {
2983                 if (IsDave2dFontFormat(m_project, m_display))
2984                 {
2985                     pixel = ((*get) << 4);
2986                 }
2987                 else
2988                 {
2989                     pixel = (*get) & 0xf0;
2990                 }
2991             }
2992 
2993             if (h & 1)
2994             {
2995                 if (IsDave2dFontFormat(m_project, m_display))
2996                 {
2997                     *put |= pixel;
2998                 }
2999                 else
3000                 {
3001                     *put |= (pixel >> 4);
3002                 }
3003             }
3004             else
3005             {
3006                 if (IsDave2dFontFormat(m_project, m_display))
3007                 {
3008                     *put = (pixel >> 4);
3009                 }
3010                 else
3011                 {
3012                     *put = pixel;
3013                 }
3014             }
3015 
3016             put -= putstride * putsign;
3017         }
3018 
3019         getrow += getstride * putsign;
3020 
3021         if (h & 1)
3022         {
3023             putrow++;
3024         }
3025     }
3026 
3027     return data;
3028 }
3029 
3030 ////////////////////////////////////////////////////////////////////////////////////////////////
Rotate1bitGlyphData(GX_CONST GX_UBYTE * map,INT width,INT height)3031 GX_UBYTE* resource_gen::Rotate1bitGlyphData(GX_CONST GX_UBYTE* map, INT width, INT height)
3032 {
3033     int datasize;
3034     int rotated_width = height;
3035     int rotated_height = width;
3036     GX_UBYTE* data;
3037     GX_UBYTE* putrow;
3038     GX_UBYTE* put;
3039     int       putstride;
3040     int       putsign;
3041     GX_UBYTE  putmask;
3042     GX_CONST GX_UBYTE* getrow;
3043     GX_CONST GX_UBYTE* get;
3044     int                getstride;
3045     GX_UBYTE           getmask;
3046     GX_UBYTE pixel;
3047 
3048     putstride = GetRowPitch(rotated_width, 1);
3049     datasize = putstride * rotated_height;
3050     data = new GX_UBYTE[datasize];
3051     memset(data, 0, datasize);
3052     putrow = data;
3053 
3054     getstride = GetRowPitch(width, 1);
3055     getrow = map;
3056 
3057     if (m_project->mDisplays[m_display].rotation_angle == GX_SCREEN_ROTATION_CW)
3058     {
3059         putrow += (rotated_height - 1) * putstride;
3060         putsign = 1;
3061     }
3062     else
3063     {
3064         // CCW
3065         getrow += (height - 1) * getstride;
3066         putsign = -1;
3067     }
3068 
3069     if (IsDave2dFontFormat(m_project, m_display))
3070     {
3071         putmask = 0x01;
3072 
3073         /* Write row from top to bottom to colum from left to right. */
3074         for (int h = 0; h < height; h++)
3075         {
3076             put = putrow;
3077             get = getrow;
3078 
3079             getmask = 0x01;
3080 
3081             for (int w = 0; w < width; w++)
3082             {
3083                 pixel = *get;
3084 
3085                 if (pixel & getmask)
3086                 {
3087                     *put |= putmask;
3088                 }
3089 
3090                 if (getmask == 0x80)
3091                 {
3092                     getmask = 0x01;
3093                     get++;
3094                 }
3095                 else
3096                 {
3097                     getmask <<= 1;
3098                 }
3099 
3100                 put -= putstride * putsign;
3101             }
3102 
3103             getrow += getstride * putsign;
3104 
3105             if (putmask == 0x80)
3106             {
3107                 putmask = 0x01;
3108                 putrow++;
3109             }
3110             else
3111             {
3112                 putmask <<= 1;
3113             }
3114         }
3115     }
3116     else
3117     {
3118         putmask = 0x80;
3119 
3120         /* Write row from top to bottom to colum from left to right. */
3121         for (int h = 0; h < height; h++)
3122         {
3123             put = putrow;
3124             get = getrow;
3125 
3126             getmask = 0x80;
3127 
3128             for (int w = 0; w < width; w++)
3129             {
3130                 pixel = *get;
3131 
3132                 if (pixel & getmask)
3133                 {
3134                     *put |= putmask;
3135                 }
3136 
3137                 if (getmask == 0x01)
3138                 {
3139                     getmask = 0x80;
3140                     get++;
3141                 }
3142                 else
3143                 {
3144                     getmask >>= 1;
3145                 }
3146 
3147                 put -= putstride * putsign;
3148             }
3149 
3150             getrow += getstride * putsign;
3151 
3152             if (putmask == 0x01)
3153             {
3154                 putmask = 0x80;
3155                 putrow++;
3156             }
3157             else
3158             {
3159                 putmask >>= 1;
3160             }
3161         }
3162     }
3163 
3164     return data;
3165 }
3166 
3167 ////////////////////////////////////////////////////////////////////////////////////////////////
RotateGlyphData(GX_CONST GX_GLYPH * glyph,GX_UBYTE font_format,GX_UBYTE ** rotated_map,INT * rotated_map_size)3168 VOID resource_gen::RotateGlyphData(GX_CONST GX_GLYPH* glyph, GX_UBYTE font_format, GX_UBYTE** rotated_map, INT* rotated_map_size)
3169 {
3170     GX_UBYTE* rotated_data = GX_NULL;
3171     GX_UBYTE* decoded_data = GX_NULL;
3172     GX_CONST GX_UBYTE* input_data;
3173 
3174     if ((font_format & GX_FONT_FORMAT_COMPRESSED) &&
3175         (((GX_COMPRESSED_GLYPH*)glyph)->gx_glyph_map_size & 0x8000))
3176     {
3177         decoded_data = RleDecodeGlyphData((GX_COMPRESSED_GLYPH*)glyph, GetFontBits(font_format));
3178         input_data = decoded_data;
3179     }
3180     else
3181     {
3182         input_data = glyph->gx_glyph_map;
3183     }
3184 
3185     if (input_data)
3186     {
3187         switch (font_format & GX_FONT_FORMAT_BPP_MASK)
3188         {
3189         case GX_FONT_FORMAT_8BPP:
3190             rotated_data = Rotate8bitGlyphData(input_data, glyph->gx_glyph_width, glyph->gx_glyph_height);
3191             break;
3192 
3193         case GX_FONT_FORMAT_4BPP:
3194             rotated_data = Rotate4bitGlyphData(input_data, glyph->gx_glyph_width, glyph->gx_glyph_height);
3195             break;
3196 
3197         case GX_FONT_FORMAT_1BPP:
3198             rotated_data = Rotate1bitGlyphData(input_data, glyph->gx_glyph_width, glyph->gx_glyph_height);
3199             break;
3200         }
3201     }
3202 
3203     if ((font_format & GX_FONT_FORMAT_COMPRESSED) && rotated_data)
3204     {
3205         if (decoded_data)
3206         {
3207             delete decoded_data;
3208         }
3209 
3210         GX_COMPRESSED_GLYPH cglyph;
3211 
3212         cglyph.gx_glyph_map = rotated_data;
3213         cglyph.gx_glyph_width = glyph->gx_glyph_height;
3214         cglyph.gx_glyph_height = glyph->gx_glyph_width;
3215 
3216         RleEncodeGlyphData(&cglyph, GetFontBits(font_format));
3217         *rotated_map = (GX_UBYTE*)cglyph.gx_glyph_map;
3218         *rotated_map_size = cglyph.gx_glyph_map_size;
3219     }
3220     else
3221     {
3222         *rotated_map = rotated_data;
3223         *rotated_map_size = 0;
3224     }
3225 }
3226 
3227 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteFontPage(const GX_FONT * font,CString & name,int page,BOOL lastpage,BOOL custom_file_enabled)3228 void resource_gen::WriteFontPage(const GX_FONT *font, CString &name, int page, BOOL lastpage, BOOL custom_file_enabled)
3229 {
3230     GX_CHAR_CODE charval;
3231     GX_CHAR_CODE index;
3232 
3233     const GX_GLYPH *glyph;
3234 
3235     const UCHAR *data;
3236     UCHAR* rotated_data = NULL;
3237     CString out;
3238     CString val;
3239     CString link;
3240     int datasize;
3241     int bytes_written = 0;
3242     int max_ascent = 0;
3243     int max_descent = 0;
3244     int max_height = 0;
3245     int guix_version = m_project->mHeader.guix_version;
3246     int* mapsize_list = GX_NULL;
3247     int  mapsize;
3248 
3249     if (!font)
3250     {
3251         return;
3252     }
3253 
3254     if (IsRotatedResourceSupported(m_project, m_display))
3255     {
3256         mapsize_list = new int[font->gx_font_last_glyph - font->gx_font_first_glyph + 1];
3257     }
3258 
3259     for (charval = font->gx_font_first_glyph; charval <= font->gx_font_last_glyph; charval++ )
3260     {
3261         index = charval - font->gx_font_first_glyph;
3262 
3263         if (font->gx_font_format & GX_FONT_FORMAT_COMPRESSED)
3264         {
3265             glyph = (GX_GLYPH *)&font->gx_font_glyphs.gx_font_compressed_glyphs[index];
3266         }
3267         else if (font->gx_font_format & GX_FONT_FORMAT_KERNING)
3268         {
3269             glyph = (GX_GLYPH *)&font->gx_font_glyphs.gx_font_kerning_glyphs[index];
3270         }
3271         else
3272         {
3273             glyph = &font->gx_font_glyphs.gx_font_normal_glyphs[index];
3274         }
3275 
3276         if (IsRotatedResourceSupported(m_project, m_display))
3277         {
3278             RotateGlyphData(glyph, font->gx_font_format, &rotated_data, &mapsize);
3279 
3280             if (font->gx_font_format & GX_FONT_FORMAT_COMPRESSED)
3281             {
3282                 datasize = mapsize & 0x7fff;
3283             }
3284             else
3285             {
3286                 datasize = GetRowPitch(glyph->gx_glyph_height, GetFontBits(font->gx_font_format));
3287                 datasize *= glyph->gx_glyph_width;
3288                 mapsize = datasize;
3289             }
3290 
3291             mapsize_list[index] = mapsize;
3292         }
3293         else
3294         {
3295             if (font->gx_font_format & GX_FONT_FORMAT_COMPRESSED)
3296             {
3297                 datasize = ((GX_COMPRESSED_GLYPH*)glyph)->gx_glyph_map_size & 0x7fff;
3298             }
3299             else
3300             {
3301                 datasize = GetRowPitch(glyph->gx_glyph_width, GetFontBits(font->gx_font_format));
3302                 datasize *= glyph->gx_glyph_height;
3303             }
3304         }
3305 
3306 
3307         if (!datasize)
3308         {
3309             continue;
3310         }
3311 
3312         out.Format(_T("static GX_CONST GX_UBYTE FONT_%s_char_%2x[%u] =\n{\n"), name, charval, datasize);
3313         FileWrite(out);
3314 
3315         bytes_written = 0;
3316         data = glyph->gx_glyph_map;
3317 
3318         out = CString("    ");
3319 
3320         BOOL written = TRUE;
3321 
3322         if (rotated_data)
3323         {
3324             data = rotated_data;
3325         }
3326         else
3327         {
3328             data = glyph->gx_glyph_map;
3329         }
3330 
3331         for (int i = 0; i < datasize; i++)
3332         {
3333             val.Format(_T("0x%02x"), *data);
3334             out += val;
3335             if (i != (datasize - 1))
3336             {
3337                 out += ", ";
3338             }
3339             written = CheckLineFeed(out);
3340             data++;
3341         }
3342 
3343         if (rotated_data)
3344         {
3345             delete rotated_data;
3346         }
3347 
3348         if (!written)
3349         {
3350             FileWrite(out);
3351         }
3352         out = CString("\n};\n");
3353         FileWrite(out);
3354 
3355         /* Write glyph kerning table after it's map data. */
3356         if (font->gx_font_format & GX_FONT_FORMAT_KERNING)
3357         {
3358             GX_CONST GX_KERNING_GLYPH *kerning_glyph = &font->gx_font_glyphs.gx_font_kerning_glyphs[index];
3359             if (kerning_glyph -> gx_kerning_table)
3360             {
3361                 WriteKerningTable(const_cast<GX_UBYTE *>(kerning_glyph->gx_kerning_table), name, charval);
3362             }
3363         }
3364     }
3365 
3366     /* Print out the font table */
3367     CString struct_name;
3368     CString glyph_cast_type = _T("");
3369     if (font->gx_font_format & GX_FONT_FORMAT_COMPRESSED)
3370     {
3371         struct_name = _T("GX_COMPRESSED_GLYPH");
3372         glyph_cast_type = _T("(GX_CONST GX_GLYPH *)");
3373     }
3374     else if (font->gx_font_format & GX_FONT_FORMAT_KERNING)
3375     {
3376         struct_name = _T("GX_KERNING_GLYPH");
3377         glyph_cast_type = _T("(GX_CONST GX_GLYPH *)");
3378     }
3379     else
3380     {
3381         struct_name = _T("GX_GLYPH");
3382     }
3383 
3384     /* Write warning text on purpose. */
3385     if (font->gx_font_format & GX_FONT_FORMAT_KERNING)
3386     {
3387         out.Format(_T("#ifndef GX_FONT_KERNING_SUPPORT\n#error GX_FONT_KERNING_SUPPORT should be defined if \'Generate Kerning Info\' is selected in font edit dialog.\n#endif\n"));
3388         FileWrite(out);
3389     }
3390 
3391     out.Format(_T("static GX_CONST %s %s_FONT_PAGE_%d_GLYPHS[%u] =\n{\n"),
3392          struct_name, name, page, (font->gx_font_last_glyph - font->gx_font_first_glyph + 1));
3393     FileWrite(out);
3394 
3395     for (charval = font->gx_font_first_glyph; charval <= font->gx_font_last_glyph; charval++ )
3396     {
3397         index = charval - font->gx_font_first_glyph;
3398         CString kerning_table_name(_T("0"));
3399 
3400         if (font->gx_font_format & GX_FONT_FORMAT_COMPRESSED)
3401         {
3402             glyph = (GX_GLYPH *)&font->gx_font_glyphs.gx_font_compressed_glyphs[index];
3403         }
3404         else if (font->gx_font_format & GX_FONT_FORMAT_KERNING)
3405         {
3406             glyph = (GX_GLYPH *)&font->gx_font_glyphs.gx_font_kerning_glyphs[index];
3407             if (((GX_KERNING_GLYPH *)glyph)->gx_kerning_table)
3408             {
3409                 kerning_table_name.Format(_T("FONT_%s_char_%2x_kerning_table"), name, charval);
3410             }
3411         }
3412         else
3413         {
3414             glyph = &font->gx_font_glyphs.gx_font_normal_glyphs[index];
3415         }
3416 
3417         if (mapsize_list)
3418         {
3419             mapsize = mapsize_list[index];
3420             datasize = mapsize & 0x7fff;
3421         }
3422         else
3423         {
3424             if (font->gx_font_format & GX_FONT_FORMAT_COMPRESSED)
3425             {
3426                 mapsize = ((GX_COMPRESSED_GLYPH*)glyph)->gx_glyph_map_size;
3427                 datasize = mapsize & 0x7fff;
3428             }
3429             else
3430             {
3431                 datasize = GetRowPitch(glyph->gx_glyph_width, GetFontBits(font->gx_font_format));
3432                 datasize *= glyph->gx_glyph_height;
3433             }
3434         }
3435 
3436         if (!datasize)
3437         {
3438             out.Format(_T("    {GX_NULL, "));
3439         }
3440         else
3441         {
3442             out.Format(_T("    {FONT_%s_char_%2x, "), name, charval);
3443         }
3444         FileWrite(out);
3445 
3446         if (guix_version < 50207)
3447         {
3448             //Generate old format for older libraries
3449             out.Format(_T("%d, %d, %d, %d, %u, %u}"),
3450                 glyph->gx_glyph_ascent,
3451                 glyph->gx_glyph_descent,
3452                 glyph->gx_glyph_advance,
3453                 glyph->gx_glyph_leading,
3454                 glyph->gx_glyph_width,
3455                 glyph->gx_glyph_height);
3456         }
3457         else if (guix_version < 50303)
3458         {
3459             //Generate new format for library version 5.2.6 or greater
3460             if (font->gx_font_format & GX_FONT_FORMAT_COMPRESSED)
3461             {
3462                 datasize = mapsize;
3463             }
3464 
3465             out.Format(_T("%d, %d, %d, %d, %d, %u, %u}"),
3466                 datasize,
3467                 glyph->gx_glyph_ascent,
3468                 glyph->gx_glyph_descent,
3469                 glyph->gx_glyph_advance,
3470                 glyph->gx_glyph_leading,
3471                 glyph->gx_glyph_width,
3472                 glyph->gx_glyph_height);
3473         }
3474         else
3475         {
3476             //Generate new format for library version 5.3.3 or greater
3477             if (font->gx_font_format & GX_FONT_FORMAT_COMPRESSED)
3478             {
3479                 out.Format(_T("%d, %d, %d, %d, %u, %u, %d}"),
3480                     glyph->gx_glyph_ascent,
3481                     glyph->gx_glyph_descent,
3482                     glyph->gx_glyph_advance,
3483                     glyph->gx_glyph_leading,
3484                     glyph->gx_glyph_width,
3485                     glyph->gx_glyph_height,
3486                     mapsize);
3487             }
3488             else if (font->gx_font_format & GX_FONT_FORMAT_KERNING)
3489             {
3490                 out.Format(_T("%d, %d, %d, %d, %u, %u, %s}"),
3491                     glyph->gx_glyph_ascent,
3492                     glyph->gx_glyph_descent,
3493                     glyph->gx_glyph_advance,
3494                     glyph->gx_glyph_leading,
3495                     glyph->gx_glyph_width,
3496                     glyph->gx_glyph_height,
3497                     kerning_table_name);
3498             }
3499             else
3500             {
3501                 out.Format(_T("%d, %d, %d, %d, %u, %u}"),
3502                     glyph->gx_glyph_ascent,
3503                     glyph->gx_glyph_descent,
3504                     glyph->gx_glyph_advance,
3505                     glyph->gx_glyph_leading,
3506                     glyph->gx_glyph_width,
3507                     glyph->gx_glyph_height);
3508             }
3509         }
3510 
3511         FileWrite(out);
3512 
3513         if(charval != font->gx_font_last_glyph)
3514         {
3515             FileWrite(CString(",\n"));
3516         }
3517         else
3518         {
3519             FileWrite(CString("\n};\n\n"));
3520         }
3521     }
3522 
3523     if (mapsize_list)
3524     {
3525         delete mapsize_list;
3526         mapsize_list = NULL;
3527     }
3528 
3529     /* Print the GX_FONT  */
3530 
3531     if (page > 1)
3532     {
3533         out.Format(_T("static GX_CONST GX_FONT %s_PAGE_%d =\n"), name, page);
3534     }
3535     else
3536     {
3537         if (custom_file_enabled)
3538         {
3539             out.Format(_T("GX_CONST GX_FONT %s = \n"), name);
3540         }
3541         else
3542         {
3543             out.Format(_T("static GX_CONST GX_FONT %s = \n"), name);
3544         }
3545     }
3546 
3547     CString font_format(_T(""));
3548 
3549     switch (font->gx_font_format & GX_FONT_FORMAT_BPP_MASK)
3550     {
3551     case GX_FONT_FORMAT_1BPP:
3552         font_format += "GX_FONT_FORMAT_1BPP";
3553         break;
3554 
3555     case GX_FONT_FORMAT_2BPP:
3556         font_format += "GX_FONT_FORMAT_2BPP";
3557         break;
3558 
3559     case GX_FONT_FORMAT_4BPP:
3560         font_format += "GX_FONT_FORMAT_4BPP";
3561         break;
3562 
3563     case GX_FONT_FORMAT_8BPP:
3564         font_format += "GX_FONT_FORMAT_8BPP";
3565         break;
3566     }
3567 
3568     if (font->gx_font_format & GX_FONT_FORMAT_COMPRESSED)
3569     {
3570         font_format += "|GX_FONT_FORMAT_COMPRESSED";
3571     }
3572 
3573     if (font->gx_font_format & GX_FONT_FORMAT_FREETYPE)
3574     {
3575         font_format += "|GX_FONT_FORMAT_FREETYPE";
3576     }
3577 
3578     if (guix_version >= 50402)
3579     {
3580         // font kerning suppot was not added until release 5.4.2
3581         if (font->gx_font_format & GX_FONT_FORMAT_KERNING)
3582         {
3583             font_format += "|GX_FONT_FORMAT_KERNING";
3584         }
3585     }
3586 
3587     if (guix_version >=  50500)
3588     {
3589         // support for this style flag was not added until release 5.5.0
3590         if (font->gx_font_format & GX_FONT_FORMAT_REVERSED_ORDER)
3591         {
3592             font_format += "|GX_FONT_FORMAT_REVERSED_ORDER";
3593         }
3594     }
3595 
3596     if (IsRotatedResourceSupported(m_project, m_display))
3597     {
3598         switch (m_project->mDisplays[m_display].rotation_angle)
3599         {
3600         case GX_SCREEN_ROTATION_CW:
3601             font_format += "|GX_FONT_FORMAT_ROTATED_90";
3602             break;
3603 
3604         case GX_SCREEN_ROTATION_CCW:
3605             font_format += "|GX_FONT_FORMAT_ROTATED_270";
3606             break;
3607         }
3608     }
3609 
3610     if (guix_version <= 50402)
3611     {
3612         link.Format(_T("{\n")
3613             _T("    %s,        /* format */\n")
3614             _T("    0,         /* line pre-space */\n")
3615             _T("    0,         /* line post-space */ \n")
3616             _T("    %u,        /* font data height */\n")
3617             _T("    %u,        /* font baseline offset */\n")
3618             _T("    0x%x,    /* first glyph within data page */\n")
3619             _T("    0x%x,    /* last glyph within data page */\n")
3620             _T("    %s%s_FONT_PAGE_%d_GLYPHS,    /* pointer to glyph data */\n"),
3621                 font_format,
3622                 font->gx_font_line_height,
3623                 font->gx_font_baseline,
3624                 font->gx_font_first_glyph,
3625                 font->gx_font_last_glyph,
3626                 glyph_cast_type, name, page);
3627     }
3628     else
3629     {
3630         link.Format(_T("{\n")
3631             _T("    %s,        /* format */\n")
3632             _T("    0,         /* line pre-space */\n")
3633             _T("    0,         /* line post-space */ \n")
3634             _T("    %u,        /* font data height */\n")
3635             _T("    %u,        /* font baseline offset */\n")
3636             _T("    0x%x,    /* first glyph within data page */\n")
3637             _T("    0x%x,    /* last glyph within data page */\n")
3638             _T("    {%s%s_FONT_PAGE_%d_GLYPHS},    /* pointer to glyph data */\n"),
3639                 font_format,
3640                 font->gx_font_line_height,
3641                 font->gx_font_baseline,
3642                 font->gx_font_first_glyph,
3643                 font->gx_font_last_glyph,
3644                 glyph_cast_type, name, page);
3645     }
3646 
3647     out += link;
3648     if (lastpage)
3649     {
3650         out += "    GX_NULL       /* next font page */\n";
3651     }
3652     else
3653     {
3654         link.Format(_T("    &%s_PAGE_%d  /* next font page */\n"), name, page + 1);
3655         out += link;
3656     }
3657     out += "};\n\n";
3658     FileWrite(out);
3659 }
3660 
3661 
3662 ////////////////////////////////////////////////////////////////////////////////////////////////
WritePixelmapStructure(res_info * pixinfo,int frame_id)3663 void resource_gen::WritePixelmapStructure(res_info *pixinfo, int frame_id)
3664 {
3665     CString out;
3666 
3667     /* Now write out the main structure. */
3668 
3669     CString name = MakePixelmapName(pixinfo, frame_id);
3670 
3671     out.Format(_T("GX_CONST GX_PIXELMAP %s_%s_%s_pixelmap =\n{\n"), UpperDisplayName(), m_ThemeName.MakeUpper(), name);
3672 
3673     FileWrite(out);
3674 
3675     out.Format(_T("    0x%08x,         /* major version */\n"), GX_CONVERT_VER);
3676     FileWrite(out);
3677 
3678     out.Format(_T("    0x%08x,         /* minor version */\n"), GX_CONVERT_SUBVER);
3679     FileWrite(out);
3680 
3681     BOOL orFlag = FALSE;
3682     out = CString("    ");
3683 
3684     if(m_map->gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
3685     {
3686         out += "GX_PIXELMAP_COMPRESSED";
3687         orFlag = TRUE;
3688     }
3689 
3690     if(m_map->gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
3691     {
3692         if (orFlag)
3693         {
3694             out += '|';
3695         }
3696         out += "GX_PIXELMAP_ALPHA";
3697         orFlag = TRUE;
3698     }
3699 
3700     if(m_map->gx_pixelmap_flags & GX_PIXELMAP_TRANSPARENT)
3701     {
3702         if (orFlag)
3703         {
3704             out += '|';
3705         }
3706         out += "GX_PIXELMAP_TRANSPARENT";
3707         orFlag = TRUE;
3708     }
3709 
3710     if(m_map -> gx_pixelmap_flags & GX_PIXELMAP_RAW_FORMAT)
3711     {
3712         if (orFlag)
3713         {
3714             out += '|';
3715         }
3716         out += "GX_PIXELMAP_RAW_FORMAT";
3717         orFlag = TRUE;
3718     }
3719 
3720     if (IsRotatedResourceSupported(m_project, m_display))
3721     {
3722         switch (m_project->mDisplays[m_display].rotation_angle)
3723         {
3724         case GX_SCREEN_ROTATION_CW:
3725             if (orFlag)
3726             {
3727                 out += '|';
3728             }
3729             if (m_project->mHeader.guix_version >= GX_VERSION_PIXELMAP_ROTATION_FLAGS_FIX)
3730             {
3731                 out += "GX_PIXELMAP_ROTATED_CW";
3732             }
3733             else
3734             {
3735                 out += "GX_PIXELMAP_ROTATED_90";
3736             }
3737             orFlag = TRUE;
3738             break;
3739 
3740         case GX_SCREEN_ROTATION_CCW:
3741             if (orFlag)
3742             {
3743                 out += '|';
3744             }
3745             if (m_project->mHeader.guix_version >= GX_VERSION_PIXELMAP_ROTATION_FLAGS_FIX)
3746             {
3747                 out += "GX_PIXELMAP_ROTATED_CCW";
3748             }
3749             else
3750             {
3751                 out += "GX_PIXELMAP_ROTATED_270";
3752             }
3753             orFlag = TRUE;
3754             break;
3755         }
3756     }
3757 
3758     if(!orFlag)
3759     {
3760         out += "0,         /* flags*/\n";
3761     }
3762     else
3763     {
3764         out += ",         /* flags*/\n";
3765     }
3766     FileWrite(out);
3767 
3768     out.Format(_T("    %s,         /* Format */\n"), GetColorFormatName(m_map->gx_pixelmap_format));
3769     FileWrite(out);
3770     out.Format(_T("    (GX_UBYTE *) %s_%s_%s_pixelmap_data,\n"), UpperDisplayName(), m_ThemeName.MakeUpper(), name);
3771     FileWrite(out);
3772 
3773     out.Format(_T("    sizeof(%s_%s_%s_pixelmap_data),    /* the size of pixelmap_data*/\n"), UpperDisplayName(), m_ThemeName.MakeUpper(), name);
3774     FileWrite(out);
3775 
3776     if(m_map -> gx_pixelmap_aux_data_size)
3777     {
3778         if (m_map->gx_pixelmap_format == GX_COLOR_FORMAT_8BIT_PALETTE)
3779         {
3780             if (pixinfo->palette_type == PALETTE_TYPE_PRIVATE)
3781             {
3782                 out.Format(_T("    (GX_UBYTE *) %s_%s_palette,\n"),
3783                     m_project->mDisplays[m_display].name, pixinfo->name);
3784                 FileWrite(out);
3785                 out.Format(_T("    sizeof(%s_%s_palette),    /* the size of pixelmap_data*/\n"),
3786                     m_project->mDisplays[m_display].name, pixinfo->name);
3787             }
3788             else
3789             {
3790                 out.Format(_T("    (GX_UBYTE *) %s_shared_palette,\n"),
3791                     m_project->mDisplays[m_display].name);
3792                 FileWrite(out);
3793                 out.Format(_T("    sizeof(%s_shared_palette),    /* the size of pixelmap_data*/\n"),
3794                     m_project->mDisplays[m_display].name);
3795 
3796             }
3797         }
3798         else
3799         {
3800             out.Format(_T("    (GX_UBYTE *) %s_%s_%s_pixelmap_aux_data,\n"),
3801                 UpperDisplayName(), m_ThemeName.MakeUpper(), name);
3802             FileWrite(out);
3803 
3804             out.Format(_T("    sizeof(%s_%s_%s_pixelmap_aux_data),    /* the size of pixelmap_data*/\n"),
3805                 UpperDisplayName(), m_ThemeName.MakeUpper(), name);
3806 
3807         }
3808 
3809     }
3810     else
3811     {
3812         out.Format(_T("    NULL,\n"));
3813         FileWrite(out);
3814         out.Format(_T("    0,     /* auxiliary data size*/\n"));
3815     }
3816     FileWrite(out);
3817 
3818     out.Format(_T("    0x%02x,    /* used for transparent iamges*/\n"), m_map->gx_pixelmap_transparent_color);
3819     FileWrite(out);
3820 
3821     out.Format(_T("    %u,        /* width in pixel*/\n"), m_map->gx_pixelmap_width);	// height
3822     FileWrite(out);
3823 
3824     out.Format(_T("    %u        /* height in pixel*/\n"), m_map->gx_pixelmap_height);
3825     FileWrite(out);
3826 
3827     out.Format(_T("};\n"));
3828     FileWrite(out);
3829 }
3830 
3831 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteRawPixelmap(res_info * pixinfo,int frame_id)3832 void resource_gen::WriteRawPixelmap(res_info *pixinfo, int frame_id)
3833 {
3834     CString path;
3835     CString out;
3836     CString val;
3837     unsigned char *data_p;
3838     UCHAR buffer[32];
3839     long file_size;
3840     long total_data_size;
3841     long total_bytes_written;
3842     int chunk_size;
3843 
3844     path = MakeAbsolutePathname(pixinfo->pathinfo);
3845     FILE *file = _tfopen(path.GetBuffer(), _T("rb"));
3846 
3847     if (!file)
3848     {
3849         return;
3850     }
3851 
3852     fseek(file, 0, SEEK_END);
3853     file_size = ftell(file);
3854 
3855     // calculate padded size
3856     if (IsRenesasDave2D(m_project) || IS_RZ_TARGET)
3857     {
3858         total_data_size = (file_size | 0x07) + 1;
3859     }
3860     else
3861     {
3862         total_data_size = file_size;
3863     }
3864 
3865     fseek(file, 0, SEEK_SET);
3866 
3867     out.Format(_T("\n/* %s_%s pixelmap data */\n\n"), m_ThemeName.MakeUpper(), pixinfo->name);
3868     FileWrite(out);
3869 
3870     // force 8 byte alignment for Dave2D target
3871     if (IsRenesasDave2D(m_project) || IS_RZ_TARGET)
3872     {
3873         out.Format(_T("#ifdef WIN32\nstatic GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] =\n#else\n"),
3874             UpperDisplayName(), m_ThemeName.MakeUpper(), pixinfo->name, total_data_size);
3875 
3876         switch(m_project->mHeader.target_tools)
3877         {
3878         case TOOLS_GNU:
3879             FileWrite(out);
3880             out.Format(_T("static GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] __attribute__((aligned(8))) ="),
3881                 UpperDisplayName(), m_ThemeName.MakeUpper(), pixinfo->name, total_data_size);
3882             out += "\n#endif\n{\n";
3883             break;
3884 
3885         case TOOLS_IAR:
3886             FileWrite(out);
3887             out.Format(_T("#pragma data_alignment=8\nstatic GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] ="),
3888                 UpperDisplayName(), m_ThemeName.MakeUpper(), pixinfo->name, total_data_size);
3889             out += "\n#endif\n{\n";
3890             break;
3891 
3892         default:
3893             out.Format(_T("static GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] =\n{\n"),
3894                 UpperDisplayName(), m_ThemeName.MakeUpper(), pixinfo->name, total_data_size);
3895             break;
3896         }
3897 
3898         FileWrite(out);
3899     }
3900     else
3901     {
3902         out.Format(_T("static GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] =\n{\n"),
3903             UpperDisplayName(), m_ThemeName.MakeUpper(), pixinfo->name, total_data_size);
3904         FileWrite(out);
3905     }
3906 
3907     total_bytes_written = 0;
3908 
3909     while(total_bytes_written < file_size)
3910     {
3911         chunk_size = fread(buffer, 1, 32, file);
3912         data_p = (unsigned char*) buffer;
3913         out = CString("    ");
3914 
3915         for(int i = 0; i < chunk_size; i++)
3916         {
3917             val.Format(_T("0x%02x"), *data_p);
3918             out += val;
3919             if (total_bytes_written != (total_data_size - 1))
3920             {
3921                 out += ", ";
3922             }
3923             data_p++;
3924             total_bytes_written++;
3925         }
3926         out += CString("\n");
3927 		FileWrite(out);
3928     }
3929 
3930     // add the padding
3931     if (total_bytes_written < total_data_size)
3932     {
3933         out = CString("    ");
3934         for(int i = total_bytes_written; i < total_data_size; i++)
3935         {
3936             val.Format(_T("0x%02x"), 0);
3937             out += val;
3938             if (i != (total_data_size - 1))
3939             {
3940                 out += ", ";
3941             }
3942         }
3943         out += CString("\n");
3944 		FileWrite(out);
3945     }
3946     out = CString("\n};\n");
3947     FileWrite(out);
3948     fclose(file);
3949 
3950     // create a temp GX_PIXELMAP structure with updated fields, write the structure,
3951     // then restore the orginal pixelmap structure pointer.
3952 
3953     GX_PIXELMAP temp_map;
3954     GX_PIXELMAP *old_map = m_map;
3955 
3956     temp_map = (*old_map);
3957     temp_map.gx_pixelmap_aux_data = GX_NULL;
3958     temp_map.gx_pixelmap_aux_data_size = 0;
3959     temp_map.gx_pixelmap_data_size = total_data_size;
3960     temp_map.gx_pixelmap_flags |= GX_PIXELMAP_RAW_FORMAT;
3961     m_map = &temp_map;
3962 
3963     WritePixelmapStructure(pixinfo, frame_id);
3964 }
3965 
RotateUIntData(GX_CONST GX_UBYTE * data,INT width,INT height)3966 GX_UBYTE* resource_gen::RotateUIntData(GX_CONST GX_UBYTE* data, INT width, INT height)
3967 {
3968     int data_size = width * height;
3969     UINT* out_data = new UINT[data_size];
3970     UINT* put_row = out_data;
3971     UINT* put;
3972     int   putsign;
3973 
3974     GX_CONST UINT* get_row = (GX_CONST UINT*)data;
3975     GX_CONST UINT* get;
3976 
3977     if (m_project->mDisplays[m_display].rotation_angle == GX_SCREEN_ROTATION_CW)
3978     {
3979         put_row += (width - 1) * height;
3980         putsign = 1;
3981     }
3982     else
3983     {
3984         put_row += (height - 1);
3985         putsign = -1;
3986     }
3987 
3988     for (int row = 0; row < height; row++)
3989     {
3990         get = get_row;
3991         put = put_row;
3992 
3993         for (int col = 0; col < width; col++)
3994         {
3995             *put = *get;
3996 
3997             get++;
3998             put -= height * putsign;
3999         }
4000 
4001         get_row += width;
4002         put_row += putsign;
4003     }
4004 
4005     return (GX_UBYTE*)out_data;
4006 }
4007 
RotateUShortData(GX_CONST GX_UBYTE * data,INT width,INT height)4008 GX_UBYTE* resource_gen::RotateUShortData(GX_CONST GX_UBYTE* data, INT width, INT height)
4009 {
4010     int data_size = width * height;
4011     USHORT* out_data = new USHORT[data_size];
4012     USHORT* put_row = out_data;
4013     USHORT* put;
4014     int     putsign;
4015 
4016     GX_CONST USHORT* get_row = (GX_CONST USHORT*)data;
4017     GX_CONST USHORT* get;
4018 
4019     if (m_project->mDisplays[m_display].rotation_angle == GX_SCREEN_ROTATION_CW)
4020     {
4021         put_row += (width - 1) * height;
4022         putsign = 1;
4023     }
4024     else
4025     {
4026         put_row += (height - 1);
4027         putsign = -1;
4028     }
4029 
4030     for (int row = 0; row < height; row++)
4031     {
4032         get = get_row;
4033         put = put_row;
4034 
4035         for (int col = 0; col < width; col++)
4036         {
4037             *put = *get;
4038 
4039             get++;
4040             put -= height * putsign;
4041         }
4042 
4043         get_row += width;
4044         put_row += putsign;
4045     }
4046 
4047     return (GX_UBYTE*)out_data;
4048 }
4049 
RotateUCharData(GX_CONST GX_UBYTE * data,INT width,INT height)4050 GX_UBYTE* resource_gen::RotateUCharData(GX_CONST GX_UBYTE* data, INT width, INT height)
4051 {
4052     int data_size = width * height;
4053     GX_UBYTE* out_data = new GX_UBYTE[data_size];
4054     GX_UBYTE* put_row = out_data;
4055     GX_UBYTE* put;
4056     int       putsign;
4057 
4058     GX_CONST GX_UBYTE* get_row = data;
4059     GX_CONST GX_UBYTE* get;
4060 
4061     if (m_project->mDisplays[m_display].rotation_angle == GX_SCREEN_ROTATION_CW)
4062     {
4063         put_row += (width - 1) * height;
4064         putsign = 1;
4065     }
4066     else
4067     {
4068         put_row += (height - 1);
4069         putsign = -1;
4070     }
4071 
4072     for (int row = 0; row < height; row++)
4073     {
4074         get = get_row;
4075         put = put_row;
4076 
4077         for (int col = 0; col < width; col++)
4078         {
4079             *put = *get;
4080 
4081             get++;
4082             put -= height * putsign;
4083         }
4084 
4085         get_row += width;
4086         put_row += putsign;
4087     }
4088 
4089     return out_data;
4090 }
4091 
RotatePixelmap(GX_PIXELMAP * map)4092 VOID resource_gen::RotatePixelmap(GX_PIXELMAP* map)
4093 {
4094     GX_UBYTE* data;
4095     GX_UBYTE* auxdata;
4096 
4097     if (!map->gx_pixelmap_data)
4098     {
4099         return;
4100     }
4101 
4102     switch (map->gx_pixelmap_format)
4103     {
4104     case GX_COLOR_FORMAT_24XRGB:
4105     case GX_COLOR_FORMAT_24BGRX:
4106     case GX_COLOR_FORMAT_32ARGB:
4107     case GX_COLOR_FORMAT_32RGBA:
4108     case GX_COLOR_FORMAT_32ABGR:
4109     case GX_COLOR_FORMAT_32BGRA:
4110         data = RotateUIntData(map->gx_pixelmap_data, map->gx_pixelmap_width, map->gx_pixelmap_height);
4111         break;
4112 
4113     case GX_COLOR_FORMAT_565RGB:
4114     case GX_COLOR_FORMAT_565BGR:
4115     case GX_COLOR_FORMAT_4444ARGB:
4116     case GX_COLOR_FORMAT_4444BGRA:
4117     case GX_COLOR_FORMAT_5551BGRX:
4118     case GX_COLOR_FORMAT_1555XRGB:
4119         data = RotateUShortData(map->gx_pixelmap_data, map->gx_pixelmap_width, map->gx_pixelmap_height);
4120 
4121         if (map->gx_pixelmap_aux_data)
4122         {
4123             auxdata = RotateUCharData(map->gx_pixelmap_aux_data, map->gx_pixelmap_width, map->gx_pixelmap_height);
4124             delete map->gx_pixelmap_aux_data;
4125             map->gx_pixelmap_aux_data = auxdata;
4126         }
4127         break;
4128 
4129     default:
4130         data = RotateUCharData(map->gx_pixelmap_data, map->gx_pixelmap_width, map->gx_pixelmap_height);
4131         break;
4132     }
4133 
4134     delete map->gx_pixelmap_data;
4135     map->gx_pixelmap_data = data;
4136 
4137     GX_SWAP_VALS(map->gx_pixelmap_width, map->gx_pixelmap_height);
4138 }
4139 
RotatePixelmap(res_info * info,int theme_id,GX_PIXELMAP * map,int frame_id)4140 GX_PIXELMAP* resource_gen::RotatePixelmap(res_info* info, int theme_id, GX_PIXELMAP *map, int frame_id)
4141 {
4142     GX_PIXELMAP* rotated_map = NULL;
4143 
4144     image_reader *pReader = NULL;
4145     CString abspath;
4146     IMAGE_INFO* default_image_info = NULL;
4147     int frame_count = 1;
4148 
4149     if (info->is_default && info->pathinfo.pathname.IsEmpty())
4150     {
4151         // Read image from internally linked system png data.
4152         PIXELMAP_RECORD* record = studiox_project::GetDefaultPixelmapRecord(info->name);
4153         if (record)
4154         {
4155             default_image_info = record->image_info;
4156             pReader = image_reader::CreateProperReader(default_image_info->data, default_image_info->data_len);
4157         }
4158     }
4159     else
4160     {
4161         abspath = MakeAbsolutePathname(info->pathinfo);
4162         pReader = image_reader::CreateProperReader(abspath);
4163         frame_count = image_reader::GetFrameCount(abspath);
4164     }
4165 
4166     if (pReader)
4167     {
4168         pReader->SetDither(info->dither);
4169 
4170         if (info->keep_alpha)
4171         {
4172             pReader->SetSaveAlphaVal(TRUE);
4173         }
4174         else
4175         {
4176             pReader->SetSaveAlphaVal(FALSE);
4177         }
4178 
4179         pReader->SetOutputColorFormat(map->gx_pixelmap_format, m_project->GetDisplayColorFormat(info));
4180 
4181         if (map->gx_pixelmap_format == GX_COLOR_FORMAT_8BIT_PALETTE)
4182         {
4183             switch (info->palette_type)
4184             {
4185             case PALETTE_TYPE_SHARED:
4186             case PALETTE_TYPE_PRIVATE:
4187                 if (m_project->mDisplays[m_display].colorformat == GX_COLOR_FORMAT_8BIT_PALETTE)
4188                 {
4189                     theme_info *info = &m_project->mDisplays[m_display].themes[theme_id];
4190                     if (info->palette)
4191                     {
4192                         pReader->SetPalette(info->palette, info->palette_total_size, info->palette_total_size);
4193                     }
4194                 }
4195                 else
4196                 {
4197                     palette_info private_palette;
4198 
4199                     private_palette.total_size = map->gx_pixelmap_aux_data_size / sizeof(GX_COLOR);
4200                     private_palette.palette = new GX_COLOR[private_palette.total_size];
4201                     memcpy(private_palette.palette, (GX_COLOR*)map->gx_pixelmap_aux_data, map->gx_pixelmap_aux_data_size); /* Use case of memcpy is verified. */
4202                     pReader->SetPalette(private_palette.palette, private_palette.total_size, private_palette.total_size);
4203                 }
4204                 break;
4205 
4206             default:
4207                 ErrorMsg("Internal Error: Invalid image palette type");
4208                 delete pReader;
4209                 return FALSE;
4210             }
4211         }
4212 
4213         BOOL result;
4214 
4215         if (default_image_info)
4216         {
4217             result = pReader->ReadImage(default_image_info->data, default_image_info->data_len);
4218         }
4219         else
4220         {
4221             result = pReader->ReadImage(abspath, frame_id);
4222         }
4223 
4224         if (result)
4225         {
4226             rotated_map = pReader->GetPixelmap();
4227             RotatePixelmap(rotated_map);
4228         }
4229 
4230         if (rotated_map)
4231         {
4232             // now compress the image
4233             if (info->compress)
4234             {
4235                 int result;
4236                 pReader->DoCompress(TRUE);
4237                 if (IsRenesasDave2D(m_project))
4238                 {
4239                     result = pReader->RleEncode(rotated_map, TRUE);
4240                 }
4241                 else
4242                 {
4243                     result = pReader->RleEncode(rotated_map);
4244                 }
4245 
4246                 if (result == FALSE)
4247                 {
4248                     info->compress = FALSE;
4249                 }
4250             }
4251 
4252             if (m_project->mDisplays[m_display].rotation_angle == GX_SCREEN_ROTATION_CW)
4253             {
4254                 rotated_map->gx_pixelmap_flags |= GX_PIXELMAP_ROTATED_CW;
4255             }
4256             else
4257             {
4258                 rotated_map->gx_pixelmap_flags |= GX_PIXELMAP_ROTATED_CCW;
4259             }
4260 
4261             GX_SWAP_VALS(rotated_map->gx_pixelmap_width, rotated_map->gx_pixelmap_height);
4262 
4263             delete pReader;
4264         }
4265     }
4266 
4267     return rotated_map;
4268 }
4269 
4270 ////////////////////////////////////////////////////////////////////////////////////////////////
WritePixelmapData(res_info * pixinfo,int theme_id,int frame_id)4271 void resource_gen::WritePixelmapData(res_info *pixinfo, int theme_id, int frame_id)
4272 {
4273 //    CString out;
4274 
4275     // m_map should be intialized by caller, and might not be same image pointed to by
4276     // info if output format does not match display format.
4277 
4278     if (!m_map)
4279     {
4280         return;
4281     }
4282 
4283     GX_PIXELMAP* rotated_map = GX_NULL;
4284 
4285     if (IsRotatedResourceSupported(m_project, m_display))
4286     {
4287         rotated_map = RotatePixelmap(pixinfo, theme_id, m_map, frame_id);
4288         m_map = rotated_map;
4289     }
4290 
4291     if (m_map->gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED &&
4292         m_map->gx_pixelmap_flags & GX_PIXELMAP_TARGA)
4293     {
4294         if (IsRenesasDave2D(m_project) &&
4295             (m_project->mHeader.target_tools == TOOLS_CCRX))
4296         {
4297                 WriteCCRXCompatibleTargaStream(pixinfo, frame_id);
4298         }
4299         else
4300         {
4301             // All targa formats are just byte streams, use UCHAR
4302             WriteUcharData(pixinfo, frame_id);
4303         }
4304     }
4305     else
4306     {
4307         switch(m_map->gx_pixelmap_format)
4308         {
4309         case GX_COLOR_FORMAT_24XRGB:
4310         case GX_COLOR_FORMAT_24BGRX:
4311         case GX_COLOR_FORMAT_32ARGB:
4312         case GX_COLOR_FORMAT_32RGBA:
4313         case GX_COLOR_FORMAT_32ABGR:
4314         case GX_COLOR_FORMAT_32BGRA:
4315             WriteUintData(pixinfo, frame_id);
4316             break;
4317 
4318         case GX_COLOR_FORMAT_565RGB:
4319         case GX_COLOR_FORMAT_565BGR:
4320         case GX_COLOR_FORMAT_4444ARGB:
4321         case GX_COLOR_FORMAT_4444BGRA:
4322         case GX_COLOR_FORMAT_5551BGRX:
4323         case GX_COLOR_FORMAT_1555XRGB:
4324             if (m_big_endian &&
4325                 (m_map->gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED) &&
4326                 (m_map->gx_pixelmap_flags & GX_PIXELMAP_ALPHA))
4327             {
4328                 WriteBigEndianCompressedUshortData(pixinfo, frame_id);
4329             }
4330             else
4331             {
4332                 WriteUshortData(pixinfo, frame_id);
4333             }
4334             break;
4335 
4336         case GX_COLOR_FORMAT_8BIT_PACKED_PIXEL:
4337             if ((m_map->gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED) &&
4338                 (m_map->gx_pixelmap_flags & GX_PIXELMAP_ALPHA))
4339             {
4340                 WriteUshortData(pixinfo, frame_id);
4341             }
4342             else
4343             {
4344                 WriteUcharData(pixinfo, frame_id);
4345             }
4346             break;
4347 
4348         default:
4349             WriteUcharData(pixinfo, frame_id);
4350             break;
4351         }
4352     }
4353 
4354     if(m_map->gx_pixelmap_aux_data)
4355     {
4356         if (pixinfo->output_color_format == GX_COLOR_FORMAT_8BIT_PALETTE)
4357         {
4358             if (pixinfo->palette_type == PALETTE_TYPE_PRIVATE)
4359             {
4360                 if (!mPrivatePaletteWritten)
4361                 {
4362                     WritePalette(m_map->gx_pixelmap_aux_data_size / 4,
4363                         (GX_COLOR*)m_map->gx_pixelmap_aux_data, pixinfo->name);
4364 
4365                     mPrivatePaletteWritten = TRUE;
4366                 }
4367             }
4368             else
4369             {
4370                 if (!mDefaultPaletteWritten)
4371                 {
4372                     WritePalette(m_map->gx_pixelmap_aux_data_size / 4,
4373                         (GX_COLOR*)m_map->gx_pixelmap_aux_data, CString("shared"));
4374 
4375                     mDefaultPaletteWritten = TRUE;
4376                 }
4377             }
4378         }
4379         else
4380         {
4381             WriteUcharAuxData(pixinfo, frame_id);
4382         }
4383     }
4384 
4385     WritePixelmapStructure(pixinfo, frame_id);
4386 
4387     if (rotated_map)
4388     {
4389         pixelmap_destroy(rotated_map);
4390     }
4391 }
4392 
4393 
4394 
4395 #ifndef COLWIDTH
4396 #define COLWIDTH 80
4397 #endif
4398 
4399 ////////////////////////////////////////////////////////////////////////////////////////////////
CheckLineFeed(CString & out)4400 BOOL resource_gen::CheckLineFeed(CString &out)
4401 {
4402 	if(out.GetLength() >= COLWIDTH)
4403 	{
4404         out += CString("\n");
4405 		FileWrite(out);
4406 
4407         out = CString("    ");
4408         return TRUE;
4409 	}
4410     return FALSE;
4411 }
4412 
4413 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteUintData(res_info * info,int res_index)4414 void resource_gen::WriteUintData(res_info *info, int res_index)
4415 {
4416     CString out;
4417     CString val;
4418     unsigned int *data_p;
4419 
4420     CString name = MakePixelmapName(info, res_index);
4421 
4422     out.Format(_T("\n/* %s_%s pixelmap data */\n\n"), m_ThemeName.MakeUpper(), name);
4423     FileWrite(out);
4424 
4425     //if (!info->qualifier.IsEmpty())
4426     //{
4427     //    out.Format("%s\n", info->qualifier);
4428     //    FileWrite(out);
4429     //}
4430 
4431     out.Format(_T("static GX_CONST UINT %s_%s_%s_pixelmap_data[%d] =\n{\n"),
4432         UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_data_size / 4);
4433 
4434 
4435     FileWrite(out);
4436 
4437     out = CString("    ");
4438 
4439     data_p = (unsigned int*) m_map->gx_pixelmap_data;
4440 
4441     BOOL written = TRUE;
4442     for(unsigned int i = 0; i < m_map->gx_pixelmap_data_size / 4; i++)
4443     {
4444         val.Format(_T("0x%08x"), *data_p);
4445         out += val;
4446         if (i != ((m_map->gx_pixelmap_data_size / 4) - 1))
4447         {
4448             out += ", ";
4449         }
4450         written = CheckLineFeed(out);
4451         data_p++;
4452     }
4453     if (!written)
4454     {
4455         FileWrite(out);
4456     }
4457     out = CString("\n};\n");
4458     FileWrite(out);
4459 }
4460 
4461 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteCCRXCompatibleTargaStream(res_info * info,int res_index)4462 void resource_gen::WriteCCRXCompatibleTargaStream(res_info* info, int res_index)
4463 {
4464     /* Targa stream is bytes, but Dave2D requires 4 byte data alignment. CCRX doesn't
4465         support any type of alignment pragma, so we write the byte data out as Ulongs.
4466     */
4467 
4468     CString out;
4469     CString val;
4470     UCHAR *pData;
4471     ULONG dataval;
4472     unsigned int loop;
4473     unsigned int bytes_left;
4474     unsigned int bytes_written;
4475 
4476     CString name = MakePixelmapName(info, res_index);
4477 
4478     out.Format(_T("\n/* %s_%s pixelmap data */\n\n"), m_ThemeName.MakeUpper(), name);
4479     FileWrite(out);
4480 
4481     out.Format(_T("static GX_CONST UINT %s_%s_%s_pixelmap_data[%d] =\n{\n"),
4482         UpperDisplayName(), m_ThemeName.MakeUpper(), name, (m_map->gx_pixelmap_data_size + 3) / 4);
4483 
4484     FileWrite(out);
4485 
4486     out = CString("    ");
4487 
4488     pData = (UCHAR *) m_map->gx_pixelmap_data;
4489 
4490     BOOL written = TRUE;
4491     bytes_written = 0;
4492 
4493     for (loop = 0; loop < m_map->gx_pixelmap_data_size / 4; loop++)
4494     {
4495         dataval = *pData++;
4496         dataval |= (*pData++) << 8;
4497         dataval |= (*pData++) << 16;
4498         dataval |= (*pData++) << 24;
4499 
4500         bytes_written += 4;
4501 
4502         val.Format(_T("0x%08x"), dataval);
4503         out += val;
4504         if (bytes_written != (m_map->gx_pixelmap_data_size))
4505         {
4506             out += ", ";
4507         }
4508         written = CheckLineFeed(out);
4509     }
4510 
4511     bytes_left = m_map->gx_pixelmap_data_size - bytes_written;
4512 
4513     if (bytes_left)
4514     {
4515         written = FALSE;
4516         dataval = 0;
4517 
4518         switch (bytes_left)
4519         {
4520         case 1:
4521             dataval = *pData++;
4522             break;
4523 
4524         case 2:
4525             dataval = *pData++;
4526             dataval |= (*pData++) << 8;
4527             break;
4528 
4529         case 3:
4530             dataval = *pData++;
4531             dataval |= (*pData++) << 8;
4532             dataval |= (*pData++) << 16;
4533             break;
4534         }
4535         val.Format(_T("0x%08x"), dataval);
4536         out += val;
4537     }
4538 
4539     if (!written)
4540     {
4541         FileWrite(out);
4542     }
4543 
4544     out = CString("\n};\n");
4545     FileWrite(out);
4546 }
4547 
4548 
4549 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteUshortData(res_info * info,int frame_id)4550 void resource_gen::WriteUshortData(res_info *info, int frame_id)
4551 {
4552     CString out;
4553     CString val;
4554     unsigned short *data_p;
4555     unsigned short data;
4556 
4557     CString name = MakePixelmapName(info, frame_id);
4558 
4559     out.Format(_T("\n/* %s_%s pixelmap data */\n\n"), m_ThemeName.MakeUpper(), name);
4560     FileWrite(out);
4561 
4562     out.Format(_T("static GX_CONST USHORT %s_%s_%s_pixelmap_data[%d] =\n{\n"),
4563         UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_data_size / 2);
4564     FileWrite(out);
4565 
4566     out = CString("    ");
4567 
4568     data_p = (unsigned short*) m_map -> gx_pixelmap_data;
4569     GX_UBYTE format = m_map ->gx_pixelmap_format;
4570 
4571     BOOL written = TRUE;
4572 
4573     for(unsigned int i = 0; i < m_map->gx_pixelmap_data_size / 2; i++)
4574     {
4575         data = *data_p;
4576         val.Format(_T("0x%04x"), data);
4577         out += val;
4578         if (i != ((m_map->gx_pixelmap_data_size / 2) - 1))
4579         {
4580             out += ", ";
4581         }
4582         written = CheckLineFeed(out);
4583         data_p++;
4584     }
4585     if (!written)
4586     {
4587         FileWrite(out);
4588     }
4589 
4590     out = CString("\n};\n");
4591     FileWrite(out);
4592 }
4593 
4594 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteBigEndianCompressedUshortData(res_info * info,int frame_id)4595 void resource_gen::WriteBigEndianCompressedUshortData(res_info *info, int frame_id)
4596 {
4597 
4598     CString out;
4599     CString val;
4600     unsigned short *pShort;
4601     unsigned char  *pByte;
4602     unsigned short  data;
4603     unsigned char   bcount;
4604     unsigned char   alpha;
4605     int pixels_to_write;
4606     ULONG bytes_written = 0;
4607 
4608     CString name = MakePixelmapName(info, frame_id);
4609     out.Format(_T("\n/* %s_%s pixelmap data */\n\n"), m_ThemeName.MakeUpper(), name);
4610     FileWrite(out);
4611 
4612     out.Format(_T("static GX_CONST USHORT %s_%s_%s_pixelmap_data[%d] =\n{\n"),
4613         UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_data_size / 2);
4614     FileWrite(out);
4615 
4616     out = CString("    ");
4617 
4618     pShort = (unsigned short*) m_map -> gx_pixelmap_data;
4619     GX_UBYTE format = m_map ->gx_pixelmap_format;
4620 
4621     BOOL written = TRUE;
4622 
4623     while(bytes_written < m_map->gx_pixelmap_data_size)
4624     {
4625         pByte = (unsigned char *) pShort;
4626         bcount = *pByte;
4627 
4628         if (bcount & 0x80)
4629         {
4630             pixels_to_write = 1;
4631         }
4632         else
4633         {
4634             pixels_to_write = bcount + 1;
4635         }
4636 
4637         for (int i = 0; i < pixels_to_write; i++)
4638         {
4639             pByte = (unsigned char *) pShort;
4640 
4641             bcount = *pByte++;
4642             alpha = *pByte++;
4643             pShort++;
4644 
4645             data = bcount;
4646             data <<= 8;
4647             data |= alpha;
4648             val.Format(_T("0x%04x"), data);
4649             out += val;
4650             out += ", ";
4651             data = *pShort++;
4652             val.Format(_T("0x%04x"), data);
4653             out += val;
4654             bytes_written += 4;
4655 
4656             if (bytes_written <= m_map->gx_pixelmap_data_size)
4657             {
4658                 out += ", ";
4659             }
4660             written = CheckLineFeed(out);
4661         }
4662     }
4663     if (!written)
4664     {
4665         FileWrite(out);
4666     }
4667 
4668     out = CString("\n};\n");
4669     FileWrite(out);
4670 }
4671 
4672 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteUcharData(res_info * info,int frame_id)4673 void resource_gen::WriteUcharData(res_info *info, int frame_id)
4674 {
4675     CString out;
4676     CString val;
4677     unsigned char *data_p;
4678 
4679     CString name = MakePixelmapName(info, frame_id);
4680     out.Format(_T("\n/* %s_%s pixelmap data */\n\n"), m_ThemeName.MakeUpper(), name);
4681     FileWrite(out);
4682 
4683     if (IsRenesasDave2D(m_project))
4684     {
4685         out.Format(_T("#ifdef WIN32\nstatic GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] =\n#else\n"),
4686             UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_data_size);
4687 
4688         switch (m_project->mHeader.target_tools)
4689         {
4690         case TOOLS_GNU:
4691             FileWrite(out);
4692             out.Format(_T("static GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] __attribute__((aligned(4))) ="),
4693                 UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_data_size);
4694             out += "\n#endif\n{\n";
4695             break;
4696 
4697         case TOOLS_IAR:
4698             FileWrite(out);
4699             out.Format(_T("#pragma data_alignment=4\nstatic GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] ="),
4700                 UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_data_size);
4701             out += "\n#endif\n{\n";
4702             break;
4703 
4704         default:
4705             out.Format(_T("static GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] =\n{\n"),
4706                 UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_data_size);
4707             break;
4708         }
4709     }
4710     else
4711     {
4712         out.Format(_T("static GX_CONST GX_UBYTE %s_%s_%s_pixelmap_data[%d] =\n{\n"),
4713             UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_data_size);
4714     }
4715     FileWrite(out);
4716 
4717     out = CString("    ");
4718 
4719     data_p = (unsigned char*) m_map->gx_pixelmap_data;
4720     BOOL written = TRUE;
4721 
4722     for(unsigned int i = 0; i < m_map->gx_pixelmap_data_size; i++)
4723     {
4724         val.Format(_T("0x%02x"), *data_p);
4725         out += val;
4726         if (i != (m_map->gx_pixelmap_data_size - 1))
4727         {
4728             out += ", ";
4729         }
4730         written = CheckLineFeed(out);
4731         data_p++;
4732     }
4733     if (!written)
4734     {
4735         FileWrite(out);
4736     }
4737     out = CString("\n};\n");
4738     FileWrite(out);
4739 
4740 }
4741 
4742 ////////////////////////////////////////////////////////////////////////////////////////////////
WriteUcharAuxData(res_info * info,int frame_id)4743 void resource_gen::WriteUcharAuxData(res_info *info, int frame_id)
4744 {
4745     CString out;
4746     CString val;
4747     unsigned char *data_p;
4748 
4749     CString name = MakePixelmapName(info, frame_id);
4750 
4751     out.Format(_T("\n/* %s_%s auxiliary data */\n\n"), m_ThemeName.MakeUpper(), name);
4752     FileWrite(out);
4753 
4754     out.Format(_T("static GX_CONST GX_UBYTE %s_%s_%s_pixelmap_aux_data[%d] =\n{\n"),
4755         UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_aux_data_size);
4756     FileWrite(out);
4757 
4758     out = CString("    ");
4759 
4760     data_p = (unsigned char*) m_map->gx_pixelmap_aux_data;
4761     BOOL written = TRUE;
4762 
4763     for(unsigned int i = 0; i < m_map->gx_pixelmap_aux_data_size; i++)
4764     {
4765         val.Format(_T("0x%02x"), *data_p);
4766         out += val;
4767         if (i != (m_map->gx_pixelmap_aux_data_size - 1))
4768         {
4769             out += ", ";
4770         }
4771         written = CheckLineFeed(out);
4772         data_p++;
4773     }
4774     if (!written)
4775     {
4776         FileWrite(out);
4777     }
4778     out = CString("\n};\n");
4779     FileWrite(out);
4780 }
4781 
4782 /////////////////////////////////////////////////////////////////////////////////////////////////
WriteUintAuxData(res_info * info,int frame_id)4783 void resource_gen::WriteUintAuxData(res_info *info, int frame_id)
4784 {
4785     CString out;
4786     CString val;
4787     unsigned int *data_p;
4788 
4789     CString name = MakePixelmapName(info, frame_id);
4790 
4791     out.Format(_T("\n/* %s_%s auxiliary data */\n\n"), m_ThemeName.MakeUpper(), name);
4792     FileWrite(out);
4793 
4794     out.Format(_T("static GX_CONST GX_COLOR %s_%s_%s_pixelmap_aux_data[%d] =\n{\n"),
4795         UpperDisplayName(), m_ThemeName.MakeUpper(), name, m_map->gx_pixelmap_aux_data_size / 4);
4796     FileWrite(out);
4797 
4798     out = CString("    ");
4799 
4800     data_p = (unsigned int*) m_map->gx_pixelmap_aux_data;
4801     BOOL written = TRUE;
4802 
4803     for(unsigned int i = 0; i < (m_map->gx_pixelmap_aux_data_size / 4); i++)
4804     {
4805         val.Format(_T("0x%08x"), *data_p);
4806         out += val;
4807         if (i != (m_map->gx_pixelmap_aux_data_size - 1))
4808         {
4809             out += ", ";
4810         }
4811         written = CheckLineFeed(out);
4812         data_p++;
4813     }
4814     if (!written)
4815     {
4816         FileWrite(out);
4817     }
4818     out = CString("\n};\n");
4819     FileWrite(out);
4820 }
4821 
4822 ////////////////////////////////////////////////////////////////////////////////////////////////
GetResourceFileName()4823 CString resource_gen::GetResourceFileName()
4824 {
4825     CString name;
4826 
4827     CCommandInfo *pCmdInfo = GetCmdInfo();
4828 
4829     if (pCmdInfo->GetResourceFileName().IsEmpty())
4830     {
4831         if (m_project->mHeader.custom_resource_enabled && (!m_project->mHeader.custom_resource_file_name.IsEmpty()))
4832         {
4833             name = m_project->mHeader.custom_resource_file_name;
4834 
4835             if (m_project->CountEnabledDisplays() > 1)
4836             {
4837                 name += "_";
4838                 name += m_project->mDisplays[m_display].name;
4839             }
4840         }
4841         else
4842         {
4843             name = m_project->mHeader.project_name;
4844 
4845             if (m_num_displays > 1)
4846             {
4847                 name += "_";
4848                 name += m_project->mDisplays[m_display].name;
4849             }
4850 
4851             name += "_resources";
4852         }
4853     }
4854     else
4855     {
4856         name = pCmdInfo->GetResourceFileName();
4857 
4858         if (m_project->CountEnabledDisplays() > 1)
4859         {
4860             name += "_";
4861             name += m_project->mDisplays[m_display].name;
4862         }
4863     }
4864 
4865     return name;
4866 }
4867 
4868 ////////////////////////////////////////////////////////////////////////////////////////////////
FontPageCompare(res_info * info_1,res_info * info_2)4869 BOOL resource_gen::FontPageCompare(res_info *info_1, res_info *info_2)
4870 {
4871     if (info_1->font_support_extended_unicode != info_2->font_support_extended_unicode)
4872     {
4873         //Font range is not equal
4874         return FALSE;
4875     }
4876 
4877     int page_count = NUM_FONT_CHAR_RANGES;
4878     if (info_1->font_support_extended_unicode)
4879     {
4880         page_count += NUM_FONT_EXTENDED_CHAR_RANGES;
4881     }
4882 
4883     for (int index = 0; index < page_count; index++)
4884     {
4885         if((info_1->font_pages[index].enabled != info_2->font_pages[index].enabled) ||
4886            (info_1->font_pages[index].first_char != info_2->font_pages[index].first_char) ||
4887            (info_1->font_pages[index].last_char != info_2->font_pages[index].last_char))
4888         {
4889             //Font range is not equal
4890             return FALSE;
4891         }
4892     }
4893 
4894     //Font range is equal
4895     return TRUE;
4896 }
4897 
4898 ////////////////////////////////////////////////////////////////////////////////////////////////
FindResourceReferenceTheme(res_info * info,int theme)4899 int resource_gen::FindResourceReferenceTheme(res_info *info, int theme)
4900 {
4901     // Check if the resource is equal to what in theme 0
4902     int refer_theme = -1;
4903     res_info *refer_info = NULL;
4904     CString abspath;
4905     CString refer_abspath;
4906     int index;
4907     int res_id;
4908 
4909     CCommandInfo *pCmdInfo = GetCmdInfo();
4910     GX_BOOL enabled;
4911 
4912     switch (info->type)
4913     {
4914     case RES_TYPE_FONT:
4915         for (index = 0; index < theme; index++)
4916         {
4917             if (pCmdInfo->IsNoGui())
4918             {
4919                 enabled = pCmdInfo->IsThemeEnabled(m_project->mDisplays[m_display].themes[index].theme_name);
4920             }
4921             else
4922             {
4923                 enabled = m_project->mDisplays[m_display].themes[index].gen_font_table;
4924             }
4925 
4926             if (enabled)
4927             {
4928                 res_id = m_project->GetResourceId(m_display, info);
4929                 refer_info = m_project->FindResource(m_display, index, info->type, res_id);
4930 
4931                 if (refer_info)
4932                 {
4933                     abspath = MakeAbsolutePathname(info->pathinfo);
4934                     refer_abspath = MakeAbsolutePathname(refer_info->pathinfo);
4935 
4936                     if ((abspath == refer_abspath) &&
4937                         (info->font_bits == refer_info->font_bits) &&
4938                         (info->font_height == refer_info->font_height) &&
4939                         FontPageCompare(info, refer_info))
4940                     {
4941                         refer_theme = index;
4942                     }
4943                 }
4944                 break;
4945             }
4946         }
4947         break;
4948 
4949     case RES_TYPE_PIXELMAP:
4950         for (index = 0; index < theme; index++)
4951         {
4952             if (pCmdInfo->IsNoGui())
4953             {
4954                 enabled = pCmdInfo->IsThemeEnabled(m_project->mDisplays[m_display].themes[index].theme_name);
4955             }
4956             else
4957             {
4958                 enabled = m_project->mDisplays[m_display].themes[index].gen_pixelmap_table;
4959             }
4960 
4961             if (enabled)
4962             {
4963                 theme_info *ti = &m_project->mDisplays[m_display].themes[index];
4964                 theme_info *refer_ti = &m_project->mDisplays[m_display].themes[theme];
4965 
4966                 if ((info->palette_type == PALETTE_TYPE_SHARED) &&
4967                     ((ti->palette_predefined != refer_ti->palette_predefined) ||
4968                      (ti->palette_total_size != refer_ti->palette_total_size) ||
4969                      (memcmp(ti->palette, refer_ti->palette, sizeof(GX_COLOR) * ti->palette_total_size) != 0)))
4970                 {
4971                     break;
4972                 }
4973 
4974                 res_id = m_project->GetResourceId(m_display, info);
4975                 refer_info = m_project->FindResource(m_display, index, info->type, res_id);
4976 
4977                 if (refer_info)
4978                 {
4979                     abspath = MakeAbsolutePathname(info->pathinfo);
4980                     refer_abspath = MakeAbsolutePathname(refer_info->pathinfo);
4981 
4982                     if ((abspath == refer_abspath) &&
4983                         (info->output_color_format == refer_info->output_color_format) &&
4984                         (info->keep_alpha == refer_info->keep_alpha) &&
4985                         (info->dither == refer_info->dither))
4986                     {
4987                         refer_theme = index;
4988                     }
4989                 }
4990                 break;
4991             }
4992         }
4993         break;
4994     }
4995 
4996     return refer_theme;
4997 }
4998 
4999 ///////////////////////////////////////////////////////////////////////////////
IsSystemPixelmap(INT pixelmap_id)5000 BOOL resource_gen::IsSystemPixelmap(INT pixelmap_id)
5001 {
5002     CCommandInfo* pCmdInfo = GetCmdInfo();
5003 
5004     if (pCmdInfo->IsXmlMode())
5005     {
5006         return FALSE;
5007     }
5008 
5009     switch (pixelmap_id)
5010     {
5011     case GX_PIXELMAP_RADIO_ON_ID:
5012     case GX_PIXELMAP_RADIO_OFF_ID:
5013     case GX_PIXELMAP_CHECKBOX_ON_ID:
5014     case GX_PIXELMAP_CHECKBOX_OFF_ID:
5015         return TRUE;
5016     }
5017 
5018     return FALSE;
5019 }
5020 
5021 ///////////////////////////////////////////////////////////////////////////////
IsResEnabled(res_info * info)5022 BOOL resource_gen::IsResEnabled(res_info* info)
5023 {
5024     if (info && info->enabled)
5025     {
5026         if ((!info->parent) || (info->parent->enabled))
5027         {
5028             return TRUE;
5029         }
5030     }
5031 
5032     return FALSE;
5033 }