ecere/gfx/newFonts: Excluding from ECERE_ONEDRIVER configurations
[sdk] / ecere / src / gfx / DisplaySystem.ec
1 namespace gfx;
2
3 #if !defined(__EMSCRIPTEN__)
4 import "Mutex"
5 #endif
6 import "Display"
7
8 const String printingDocumentName;
9
10 public void SetPrintingDocumentName(const String name)
11 {
12    printingDocumentName = name;
13 }
14
15 public class DisplaySystemResPtr : struct
16 {
17    DisplaySystemResPtr prev, next;
18    Resource resource;
19 };
20
21 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
22 static void FreeTexture(NamedLink texture)
23 {
24    Bitmap bitmap = texture.data;
25    bitmap.Free();
26    delete bitmap;
27    delete texture.name;
28 }
29
30 static void FreeMaterial(Material material)
31 {
32    delete material.name;
33 }
34 #endif
35
36 public class DisplaySystem
37 {
38 public:
39    class_no_expansion;
40    ~DisplaySystem()
41    {
42 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
43       OldLink mesh;
44
45       materials.Free(Material::Free);
46       textures.Free(FreeTexture);
47       for(mesh = meshes.first; mesh; mesh = mesh.next)
48          ((Mesh)mesh.data).Free(0);
49       meshes.Free(null);
50 #endif
51
52       if(driverData)
53          driver.DestroyDisplaySystem(this);
54
55       if(driver.displaySystem == this)
56          driver.displaySystem = null;
57    }
58
59    bool Create(const char * driverName, void * window, bool fullScreen)
60    {
61       bool result = false;
62       subclass(DisplayDriver) displayDriver = GetDisplayDriver(driverName);
63       if(displayDriver)
64       {
65          flags.fullScreen = fullScreen;
66          this.window = window;
67          if(displayDriver.CreateDisplaySystem(this))
68             result = true;
69
70          driver = displayDriver;
71          if(!result)
72          {
73             // LogErrorCode(GERR_DISPLAY_INIT_FAILED, driver);
74             displayDriver.displaySystem = null;
75          }
76          else if(!displayDriver.displaySystem)
77          {
78             displayDriver.displaySystem = this;
79          }
80       }
81       return result;
82    }
83
84    Font LoadOutlineFont(const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
85    {
86       Font result = null;
87       subclass(DisplayDriver) driver = this ? this.driver : ((subclass(DisplayDriver))class(LFBDisplayDriver));
88       char * string = CopyString(faceName);
89       char *fonts[32];
90       if(string)
91       {
92          int numFonts = TokenizeWith(string, 32, fonts, ",", true);
93          int c;
94          for(c = 0; c<numFonts; c++)
95          {
96             TrimLSpaces(fonts[c],fonts[c]);
97             TrimRSpaces(fonts[c],fonts[c]);
98             if((result = driver.LoadFont(this, fonts[c], size, flags, outlineSize, outlineFade)))
99             {
100                break;
101             }
102          }
103          delete string;
104       }
105       return result;
106    }
107
108    Font LoadFont(const char * faceName, float size, FontFlags flags)
109    {
110       return LoadOutlineFont(faceName, size, flags, 0, 0);
111    }
112
113    void UnloadFont(Font font)
114    {
115       subclass(DisplayDriver) driver = this ? this.driver : ((subclass(DisplayDriver))class(LFBDisplayDriver));
116       driver.UnloadFont(this, font);
117    }
118
119    void FontExtent(Font font, const char * text, int len, int * width, int * height)
120    {
121       if(this && text)
122       {
123          int advance = 0;
124          driver.FontExtent(this, font, text, len, width, height, 0, null, &advance);
125          if(width) *width += advance;
126       }
127       else
128       {
129          if(width) *width = 0;
130          if(height) *height = 0;
131       }
132    }
133
134    void FontExtent2(Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * overHang)
135    {
136       if(this && text)
137          driver.FontExtent(this, font, text, len, width, height, prevGlyph, rPrevGlyph, overHang);
138       else
139       {
140          if(width) *width = 0;
141          if(height) *height = 0;
142       }
143    }
144
145    void * _LoadResource(Resource resource, void * fm)
146    {
147       DisplaySystemResPtr res;
148       for(res = resources.first; res; res = res.next)
149       {
150          Resource existing = res.resource;
151
152          if(existing._class == resource._class)
153          {
154             if(resource.OnCompare(existing) == 0)
155                break;
156          }
157       }
158       if(!res)
159       {
160          // res = DisplaySystemResPtr { resource = new classof(resource) };
161          res = DisplaySystemResPtr { resource = eInstance_New(resource._class) };
162          resources.Add(res);
163
164          // This will load e.g. the Bitmap *
165 #if !defined(ECERE_VANILLA) && !defined(ECERE_ONEDRIVER)
166          if(fm)
167          {
168             ((FontResource)res.resource).LoadFM((FontResource)resource, this, fm);
169          }
170          else
171 #endif
172             res.resource.Load(resource, this);
173       }
174 #if !defined(ECERE_VANILLA) && !defined(ECERE_ONEDRIVER)
175       else if(fm)
176       {
177          FontResource fr = (FontResource)res.resource;
178          if(!fr.fmFont)
179          {
180             FontManager fMgr = (FontManager)fm;
181             fr.fmFont = fMgr.getFont(fr);
182             fr.fm = fm;
183          }
184          if(!fr.font)
185          {
186             fr.font = LoadFont(fr.faceName, fr.size, fr.flags);
187             fr.displaySystem = this;
188          }
189       }
190 #endif
191       // This would copy e.g. the Bitmap *
192       incref res.resource;
193       resource.Reference(res.resource);
194
195       return res;
196    }
197
198    void * LoadResource(Resource resource)
199    {
200       return _LoadResource(resource, null);
201    }
202
203 #if !defined(ECERE_VANILLA) && !defined(ECERE_ONEDRIVER)
204    void * LoadResourceFM(Resource resource, FontManager fm)
205    {
206       return _LoadResource(resource, fm);
207    }
208 #endif
209
210    void UnloadResource(Resource resource, DisplaySystemResPtr res)
211    {
212       // This would clear e.g. the Bitmap *
213       resource.Dereference();
214       if(res)
215       {
216          if(res.resource._refCount == 1)
217          {
218             delete res.resource;
219             resources.Delete(res);
220          }
221          else
222             res.resource._refCount--;
223       }
224    }
225
226    bool Lock()
227    {
228       bool result = false;
229 #if !defined(__EMSCRIPTEN__)
230       mutex.Wait();
231 #endif
232
233       if(!current)
234          result = driver.LockSystem(this);
235       else
236          result = true;
237       current++;
238       return result;
239    }
240
241    void Unlock(void)
242    {
243       current--;
244       if(!current)
245          driver.UnlockSystem(this);
246
247 #if !defined(__EMSCRIPTEN__)
248       mutex.Release();
249 #endif
250    }
251 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
252    // --- Materials List Management ---
253
254    Material AddNamedMaterial(const char * name)
255    {
256       Material material = materials.FindName(name, false);
257       if(!material)
258       {
259          material = Material { };
260          if(material)
261          {
262             material.name = CopyString(name);
263             if(name)
264                materials.AddName(material);
265             else
266                materials.Add(material);
267          }
268       }
269       return material;
270    }
271
272    bool AddMaterial(Material material)
273    {
274       if(material.name)
275          materials.AddName(material);
276       else
277          materials.Add(material);
278       return true;
279    }
280
281    Material GetMaterial(const char * name)
282    {
283       return materials.FindName(name, false);
284    }
285
286    bool RemoveMaterial(Material material)
287    {
288       delete material.name;
289       materials.Delete(material);
290       return true;
291    }
292
293    void ClearMaterials()
294    {
295       materials.Free(FreeMaterial);
296    }
297
298    // --- Textures List Management ---
299
300    NamedLink AddTexture(const char * name, Bitmap bitmap)
301    {
302       NamedLink item { };
303       if(item)
304       {
305          item.data = bitmap;
306          incref bitmap;
307          item.name = new char[strlen(name) + 1];
308          strcpy(item.name, name);
309          textures.AddName(item);
310       }
311       return item;
312    }
313
314    Bitmap GetTexture(const char * name)
315    {
316       return textures.FindNamedLink(name, false);
317    }
318
319    bool RemoveTexture(const char * name)
320    {
321       NamedLink item = textures.FindName(name, false);
322       if(item)
323       {
324          FreeTexture(item);
325          textures.Delete(item);
326          return true;
327       }
328       return false;
329    }
330
331    void ClearTextures()
332    {
333       textures.Free(FreeTexture);
334    }
335
336    // --- Meshes List Management ---
337
338    OldLink AddMesh(Mesh mesh)
339    {
340       if(this)
341       {
342          OldLink item { };
343          if(item)
344          {
345             item.data = mesh;
346             mesh.displaySystem = this;
347             meshes.Add(item);
348          }
349          return item;
350       }
351       return null;
352    }
353
354    bool RemoveMesh(Mesh mesh)
355    {
356       OldLink item = meshes.FindLink(mesh);
357       if(item)
358       {
359          mesh.Free(0);
360          meshes.Delete(item);
361          return true;
362       }
363       return false;
364    }
365
366    void ClearMeshes()
367    {
368       OldLink mesh;
369       for(mesh = meshes.first; mesh; mesh = mesh.next)
370          ((Mesh)mesh.data).Free(0);
371       meshes.Free(null);
372    }
373 #endif
374
375 private:
376    subclass(DisplayDriver) driver;
377    void * data;
378    void * window;
379    public PixelFormat pixelFormat;
380    public DisplayFlags flags;
381    int numDisplays;
382    GLCapabilities glCapabilities;
383
384    OldList resources;
385
386 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
387    // This will all go in resources
388    OldList materials;
389    OldList textures;
390    OldList meshes;
391 #endif
392
393    void * driverData;
394    int current;
395 #if !defined(__EMSCRIPTEN__)
396    Mutex mutex { };
397 #endif
398 };