@@ -676,3 +676,99 @@ void Fl_GDI_Graphics_Driver::rtl_draw_unscaled(const char* c, int n, int x, int
676676 SetTextColor (gc_, oldColor);
677677}
678678#endif
679+
680+ // Memory font loading for Windows using AddFontMemResourceEx
681+
682+ /* *
683+ Load a TrueType or OpenType font from memory.
684+ \param data Pointer to the font data in memory.
685+ \param data_size Size of the font data in bytes.
686+ \param font_name Name to register the font with, or NULL to use the embedded name.
687+ \return Font number on success, or (Fl_Font)-1 on failure.
688+ */
689+ Fl_Font Fl_GDI_Graphics_Driver::load_font (const void * data, size_t data_size, const char * font_name) {
690+ if (!data || data_size == 0 ) return (Fl_Font)-1 ;
691+
692+ // Add font to Windows using AddFontMemResourceEx
693+ DWORD num_fonts = 0 ;
694+ HANDLE font_handle = AddFontMemResourceEx ((PVOID)data, (DWORD)data_size, NULL , &num_fonts);
695+ if (!font_handle || num_fonts == 0 ) {
696+ return (Fl_Font)-1 ;
697+ }
698+
699+ // Get the font name from the font data if not provided
700+ const char * name_to_use = font_name;
701+ char * allocated_name = NULL ;
702+
703+ if (!name_to_use) {
704+ // Try to extract the font family name from the TrueType font data
705+ // The TrueType 'name' table (table ID 6) contains the font family name
706+ // For simplicity, we require the caller to provide a name
707+ // since parsing the name table is complex
708+ RemoveFontMemResourceEx (font_handle);
709+ return (Fl_Font)-1 ;
710+ }
711+
712+ // Create a name with the required prefix for the platform (space = normal)
713+ size_t name_len = strlen (name_to_use);
714+ allocated_name = (char *)malloc (name_len + 2 );
715+ if (!allocated_name) {
716+ RemoveFontMemResourceEx (font_handle);
717+ return (Fl_Font)-1 ;
718+ }
719+ allocated_name[0 ] = ' ' ; // Normal weight/style prefix
720+ memcpy (allocated_name + 1 , name_to_use, name_len + 1 );
721+
722+ // Find a free font slot
723+ Fl_Font fnum = Fl::set_fonts (NULL );
724+ if (fnum == 0 ) fnum = FL_FREE_FONT;
725+
726+ // Register the font
727+ Fl::set_font (fnum, allocated_name);
728+
729+ // Store the memory font information
730+ unsigned width = font_desc_size ();
731+ Fl_Fontdesc *s = (Fl_Fontdesc*)((char *)fl_fonts + fnum * width);
732+ s->mem_font_data = data;
733+ s->mem_font_size = data_size;
734+ s->mem_font_handle = font_handle;
735+
736+ return fnum;
737+ }
738+
739+ /* *
740+ Unload a font previously loaded with load_font().
741+ \param font The font number returned by load_font().
742+ */
743+ void Fl_GDI_Graphics_Driver::unload_font (Fl_Font font) {
744+ if (font < FL_FREE_FONT) return ;
745+
746+ unsigned width = font_desc_size ();
747+ Fl_Fontdesc *s = (Fl_Fontdesc*)((char *)fl_fonts + font * width);
748+
749+ // Check if this is a memory font
750+ if (s->mem_font_handle ) {
751+ // Delete any cached font descriptors
752+ for (Fl_Font_Descriptor* f = s->first ; f;) {
753+ Fl_Font_Descriptor* n = f->next ;
754+ delete f;
755+ f = n;
756+ }
757+ s->first = NULL ;
758+
759+ // Remove the font from Windows
760+ RemoveFontMemResourceEx ((HANDLE)s->mem_font_handle );
761+
762+ // Free the allocated name (allocated in load_font)
763+ if (s->name ) {
764+ free ((void *)s->name );
765+ }
766+
767+ // Clear the font descriptor
768+ s->name = NULL ;
769+ s->fontname [0 ] = 0 ;
770+ s->mem_font_data = NULL ;
771+ s->mem_font_size = 0 ;
772+ s->mem_font_handle = NULL ;
773+ }
774+ }
0 commit comments