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