1  typedef struct HDC__ { int unused; } *HDC;
       2  typedef struct HFONT__ { int unused; } *HFONT;
       3  
       4  void* HeapAlloc(void*,unsigned int,unsigned long);
       5  extern int memcmp (const void *, const void *, __SIZE_TYPE__);
       6  
       7  typedef struct tagLOGFONTW
       8  {
       9      int lfPitchAndFamily;
      10      unsigned short lfFaceName[32];
      11  } LOGFONTW, *PLOGFONTW, *LPLOGFONTW;
      12  
      13  typedef struct tagGdiFont GdiFont;
      14  typedef struct tagDC DC;
      15  
      16  extern unsigned int WineEngGetFontData(GdiFont*, unsigned int, unsigned int, void*, unsigned int);
      17  
      18  struct list
      19  {
      20      struct list *next;
      21      struct list *prev;
      22  };
      23  
      24  typedef struct FT_FaceRec_
      25  {
      26    signed long face_flags;
      27  } FT_FaceRec, *FT_Face;
      28  
      29  typedef struct { } GM;
      30  
      31  typedef struct { } FMAT2;
      32  
      33  typedef struct {
      34      unsigned int hash;
      35      LOGFONTW lf;
      36      int can_use_bitmap;
      37  } FONT_DESC;
      38  
      39  
      40  
      41  typedef struct tagHFONTLIST {
      42      struct list entry;
      43      HFONT hfont;
      44  } HFONTLIST;
      45  
      46  typedef struct {
      47      struct list entry;
      48      void *face;
      49      GdiFont *font;
      50  } CHILD_FONT;
      51  
      52  
      53  struct tagGdiFont {
      54      struct list entry;
      55      GM **gm;
      56      struct list hfontlist;
      57      struct list child_fonts;
      58  
      59      FT_Face ft_face;
      60      FONT_DESC font_desc;
      61      long ppem;
      62  };
      63  
      64  
      65  
      66  static struct list gdi_font_list = { &(gdi_font_list), &(gdi_font_list) };
      67  
      68  
      69  
      70  
      71  static int get_glyph_index_linked(GdiFont *font, unsigned int c, GdiFont **linked_font, unsigned int *glyph);
      72  static long load_VDMX(GdiFont*, long);
      73  
      74  extern int f1(void*,int);
      75  extern int strcmpiW (const void*,const void*);
      76  
      77  static FT_Face OpenFontFace(GdiFont *font, void *face, long width, long height)
      78  {
      79     FT_Face ft_face;
      80  
      81     font->ppem = load_VDMX(font, height);
      82     if(font->ppem == 0)
      83         font->ppem = f1(ft_face, height);
      84     return ft_face;
      85  }
      86  
      87  
      88  static GdiFont *alloc_font(void)
      89  {
      90      GdiFont *ret = HeapAlloc(0, 0x00000008, sizeof(*ret));
      91      ret->gm = HeapAlloc(0, 0x00000008, sizeof(GM*));
      92      return ret;
      93  }
      94  
      95  
      96  static long load_VDMX(GdiFont *font,long height)
      97  {
      98      unsigned short hdr[3];
      99  
     100      WineEngGetFontData(font, 0x42424242, 0, hdr, 6);
     101      return 0;
     102  }
     103  
     104  static int fontcmp(const GdiFont *font, FONT_DESC *fd)
     105  {
     106      if(font->font_desc.hash != fd->hash) return 1;
     107      if(memcmp(&font->font_desc.lf, &fd->lf, __builtin_offsetof (LOGFONTW, lfFaceName))) return 1;
     108      if(!font->font_desc.can_use_bitmap != !fd->can_use_bitmap) return 1;
     109      return strcmpiW(font->font_desc.lf.lfFaceName, fd->lf.lfFaceName);
     110  }
     111  
     112  static GdiFont *find_in_cache(HFONT hfont, const LOGFONTW *plf, const FMAT2 *pmat, int can_use_bitmap)
     113  {
     114      GdiFont *ret;
     115      FONT_DESC fd;
     116      HFONTLIST *hflist;
     117      struct list *font_elem_ptr, *hfontlist_elem_ptr;
     118  
     119      fd.lf = *plf;
     120      fd.can_use_bitmap = can_use_bitmap;
     121  
     122  
     123      for ((font_elem_ptr) = (&gdi_font_list)->next; (font_elem_ptr) != (&gdi_font_list); (font_elem_ptr) = (font_elem_ptr)->next) {
     124          ret = ((struct tagGdiFont *)((char *)(font_elem_ptr) - (unsigned long)(&((struct tagGdiFont *)0)->entry)));
     125          if(!fontcmp(ret, &fd)) {
     126              if(!can_use_bitmap && !( ret->ft_face->face_flags & ( 1L << 0 ) )) continue;
     127              for ((hfontlist_elem_ptr) = (&ret->hfontlist)->next; (hfontlist_elem_ptr) != (&ret->hfontlist); (hfontlist_elem_ptr) = (hfontlist_elem_ptr)->next) {
     128                  hflist = ((struct tagHFONTLIST *)((char *)(hfontlist_elem_ptr) - (unsigned long)(&((struct tagHFONTLIST *)0)->entry)));
     129                  if(hflist->hfont == hfont)
     130                      return ret;
     131              }
     132              hflist = HeapAlloc(0, 0, sizeof(*hflist));
     133              hflist->hfont = hfont;
     134              return ret;
     135          }
     136      }
     137  
     138      while(font_elem_ptr) {
     139          ret = ((struct tagGdiFont *)((char *)(font_elem_ptr) - (unsigned long)(&((struct tagGdiFont *)0)->entry)));
     140          if(!fontcmp(ret, &fd)) {
     141              if(!can_use_bitmap && !( ret->ft_face->face_flags & ( 1L << 0 ) )) continue;
     142              hflist = HeapAlloc(0, 0, sizeof(*hflist));
     143              hflist->hfont = hfont;
     144              return ret;
     145          }
     146      }
     147      return ((void *)0);
     148  }
     149  
     150  
     151  
     152  
     153  GdiFont *WineEngCreateFontInstance(DC *dc, HFONT hfont)
     154  {
     155      GdiFont *ret;
     156      int can_use_bitmap;
     157      LOGFONTW lf;
     158      FMAT2 dcmat;
     159  
     160      if((ret = find_in_cache(hfont, &lf, &dcmat, can_use_bitmap)) != ((void *)0))
     161          return ret;
     162      return alloc_font();
     163  }
     164  
     165  extern unsigned int f(void*,unsigned int g);
     166  
     167  static unsigned int get_glyph_index(void*font, unsigned int glyph)
     168  {
     169      return f(font, glyph);
     170  }
     171  
     172  unsigned int WineEngGetGlyphOutline(GdiFont *incoming_font, unsigned int glyph, unsigned int format,
     173          void* lpgm, unsigned int buflen, void* buf,
     174          const void* lpmat)
     175  {
     176      unsigned int glyph_index;
     177  
     178      get_glyph_index_linked(incoming_font, glyph, &incoming_font, &glyph_index);
     179      return 0;
     180  }
     181  
     182  static int load_child_font(GdiFont *font, CHILD_FONT *child)
     183  {
     184      child->font = alloc_font();
     185      child->font->ft_face = OpenFontFace(child->font, child->face, 0, -font->ppem);
     186      if(!child->font->ft_face)
     187          return 0;
     188      return 1;
     189  }
     190  
     191  static int get_glyph_index_linked(GdiFont *font, unsigned int c, GdiFont **linked_font, unsigned int *glyph)
     192  {
     193      unsigned int g;
     194      CHILD_FONT *child_font;
     195  
     196      for ((child_font) = ((CHILD_FONT *)((char *)((&font->child_fonts)->next) - (unsigned long)(&((CHILD_FONT *)0)->entry))); &(child_font)->entry != (&font->child_fonts); (child_font) = ((CHILD_FONT *)((char *)((child_font)->entry.next) - (unsigned long)(&((CHILD_FONT *)0)->entry))))
     197      {
     198          if(!load_child_font(font, child_font))
     199              continue;
     200  
     201          g = get_glyph_index(child_font->font, c);
     202          if(g) {
     203              *glyph = g;
     204              *linked_font = child_font->font;
     205              return 1;
     206          }
     207      }
     208      return 0;
     209  }
     210  
     211  void load_sfnt_table ();
     212  
     213  unsigned int WineEngGetFontData(GdiFont *font, unsigned int table, unsigned int offset, void* buf,
     214      unsigned int cbData)
     215  {
     216      unsigned long len;
     217      load_sfnt_table(font->ft_face, table, offset, buf, &len);
     218      return len;
     219  }
     220  
     221  int WineEngGetLinkedHFont(DC *dc, unsigned short c, HFONT *new_hfont, unsigned int *glyph) {
     222      return get_glyph_index_linked(0, 0, 0, 0);
     223  }
     224