1 /** 2 * Retrograde Engine 3 * 4 * Authors: 5 * Mike Bierlee, m.bierlee@lostmoment.com 6 * Copyright: 2014-2021 Mike Bierlee 7 * License: 8 * This software is licensed under the terms of the MIT license. 9 * The full terms of the license can be found in the LICENSE.txt file. 10 */ 11 12 module retrograde.graphics.twodee.sdl2.text; 13 14 version(Have_derelict_sdl2) { 15 16 import retrograde.entity; 17 import retrograde.font; 18 import retrograde.graphics.twodee.sdl2.rendering; 19 import retrograde.file; 20 import retrograde.graphics.core; 21 import retrograde.stringid; 22 23 import derelict.sdl2.ttf; 24 import derelict.sdl2.sdl; 25 26 import poodinis; 27 28 import std.typecons; 29 import std.string; 30 import std.conv; 31 import std.exception; 32 33 class Sdl2TextProcessor : EntityProcessor { 34 35 @Autowire 36 private Sdl2RenderSystem renderer; 37 38 public override bool acceptsEntity(Entity entity) { 39 return entity.hasComponent!RenderableTextComponent 40 && entity.hasComponent!FontComponent 41 && entity.hasComponent!TextComponent 42 && entity.hasComponent!TextureComponent; 43 } 44 45 public override void update() { 46 foreach(entity; _entities.getAll()) { 47 renderEntityText(entity); 48 } 49 } 50 51 private void renderEntityText(Entity entity) { 52 entity.withComponent!TextComponent((component) { 53 if (component.isChanged()) { 54 auto fontComponent = entity.getComponent!FontComponent; 55 auto font = cast(Sdl2Font) fontComponent.font; 56 if (font is null) { 57 return; 58 } 59 60 TTF_Font* ttfFont = font.ttfFont; 61 SDL_Surface* surface = TTF_RenderUTF8_Blended(ttfFont, component.text.toStringz(), SDL_Color(255, 255, 255, 255)); 62 SDL_Texture* texture = renderer.createTextureFromSurface(surface); 63 SDL_FreeSurface(surface); 64 auto textureComponent = entity.getComponent!TextureComponent; 65 // TODO: Free old texture? 66 textureComponent.texture = new Sdl2Texture(texture, font.fontName); 67 component.clearChanged(); 68 } 69 }); 70 } 71 72 } 73 74 class Sdl2Font : Font { 75 private TTF_Font* _ttfFont; 76 77 public TTF_Font* ttfFont() { 78 return _ttfFont; 79 } 80 81 this(TTF_Font* ttfFont, string fontName, uint pointSize, ulong index) { 82 super(fontName, pointSize, index); 83 this._ttfFont = ttfFont; 84 } 85 } 86 87 class FontLoadException : Exception { 88 mixin basicExceptionCtors; 89 } 90 91 class Sdl2FontComponentFactory : FontComponentFactory { 92 private FontComponent[Tuple!(string, uint, ulong)] fontComponentCache; 93 94 public override FontComponent create(File fontFile, uint pointSize, ulong index = 0) { 95 auto key = tuple(fontFile.fileName, pointSize, index); 96 auto cachedComponent = key in fontComponentCache; 97 if (cachedComponent) { 98 return *cachedComponent; 99 } 100 101 auto loadedFont = TTF_OpenFontIndex(fontFile.fileName.toStringz(), cast(int) pointSize, cast(int) index); 102 if (!loadedFont) { 103 throw new FontLoadException(format("Cannot load %s: %s", fontFile.fileName, to!string(TTF_GetError()))); 104 } 105 106 auto newComponent = new FontComponent(new Sdl2Font(loadedFont, fontFile.fileName, pointSize, index)); 107 fontComponentCache[key] = newComponent; 108 return newComponent; 109 } 110 } 111 112 }