1 /+
2 The MIT License (MIT)
3 
4     Copyright (c) <2013> <Oleg Butko (deviator), Anton Akzhigitov (Akzwar)>
5 
6     Permission is hereby granted, free of charge, to any person obtaining a copy
7     of this software and associated documentation files (the "Software"), to deal
8     in the Software without restriction, including without limitation the rights
9     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10     copies of the Software, and to permit persons to whom the Software is
11     furnished to do so, subject to the following conditions:
12 
13     The above copyright notice and this permission notice shall be included in
14     all copies or substantial portions of the Software.
15 
16     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22     THE SOFTWARE.
23 +/
24 
25 module desgui.core.textrect;
26 
27 import desgui.core.textrender;
28 import desgui.core.draw;
29 import desgui.core.except;
30 
31 class DiTextRectException: DiException 
32 { 
33     @safe pure nothrow this( string msg, string file=__FILE__, size_t line=__LINE__ )
34     { super( msg, file, line ); } 
35 }
36 
37 class DiTextRect : DiDrawable
38 {
39 protected:
40     DiTextRender textRender;
41     DiGlyphRender glyphRender;
42 
43     DiGlyphInfo p_glyph;
44     DiGlyphParam p_param;
45 
46     DiDrawRect p_plane;
47 
48     wstring p_text;
49 
50     ivec2 loffset = ivec2(0,0);
51 
52     final void repos()
53     { p_plane.reshape( irect( p_glyph.pos + loffset, p_glyph.size ) ); }
54 
55     void update()
56     {
57         p_glyph = textRender( glyphRender, p_param, p_text );
58         p_plane.image( p_glyph.img );
59         repos();
60     }
61 
62 public:
63 
64     this( DiTextRender tr, DiGlyphRender gr, DiDrawRect dr ) 
65     { 
66         if( dr is null )
67             throw new DiTextRectException( "draw rect for DiTextRect is null" );
68 
69         p_plane = dr;
70         p_plane.useTexture = p_plane.UseTexture.FULL;
71 
72         setRenders( tr, gr );
73     }
74 
75     @property
76     {
77         ivec2 pos() const { return loffset; }
78 
79         void pos( in ivec2 offset )
80         { 
81             loffset = offset;
82             repos();
83         }
84 
85         irect rect() const { return p_plane.rect; }
86 
87         ref const(DiGlyphInfo) glyph() const nothrow { return p_glyph; }
88 
89         wstring text() const nothrow { return p_text; }
90         void text( wstring str ) 
91         { 
92             if( p_text != str )
93             {
94                 p_text = str; 
95                 update(); 
96             }
97         }
98 
99         ref const(DiGlyphParam) param() const nothrow { return p_param; }
100         void param( in DiGlyphParam par ) 
101         { 
102             if( p_param != par )
103             {
104                 p_param = par; 
105                 update(); 
106             }
107         }
108     }
109 
110     void draw() { p_plane.draw(); }
111 
112     void setRenders( DiTextRender tr, DiGlyphRender gr )
113     {
114         if( tr is null )
115             throw new DiTextRectException( "text render for DiTextRect is null" );
116         if( gr is null )
117             throw new DiTextRectException( "glyph render for DiTextRect is null" );
118 
119         textRender = tr;
120         glyphRender = gr;
121 
122         update();
123     }
124 }
125 
126 unittest
127 {
128     import desil.image;
129     import desgui.core.context;
130     void printImage( in Image img )
131     {
132         import std.stdio;
133         foreach( y; 0 .. img.size.h )
134         {
135             foreach( x; 0 .. img.size.w )
136             {
137                 auto v = img.read!ubyte(x,y);
138                 char r;
139                 switch(v)
140                 {
141                     case 0: r = '`'; break;
142                     case 8: r = '#'; break;
143                     default: r = '*'; break;
144                 }
145                 stderr.write( r );
146             }
147             stderr.writeln();
148         }
149         stderr.writeln();
150     }
151 
152     auto tgr = new TestGlyphRender();
153     auto bltr = new DiBaseLineTextRender();
154     auto ddr = new TestDrawRect( irect(0,0,1,1) );
155     
156     auto dtr = new DiTextRect( bltr, tgr, ddr );
157 
158     auto im = Image( screen );
159     dtr.text = "test test"w;
160     dtr.draw();
161     assert( screen == im );
162     clearScreen();
163 
164     auto ttim = Image( imsize_t( 51,5 ), ImageType( ImCompType.UBYTE, 1 ), data_test_test );
165     im = Image( screen );
166     im.paste( ivec2(0,-2), ttim );
167     dtr.pos = ivec2( 0, 3 );
168     dtr.draw();
169 
170     assert( screen == im );
171     clearScreen();
172 
173     auto ttimStr = Image( imsize_t( 51,5 ), ImageType( ImCompType.UBYTE, 1 ), data_test_test_str );
174     im = Image( screen );
175     im.paste( ivec2(4,3), ttimStr );
176     dtr.pos = ivec2(4,8);
177     assert( dtr.glyph.pos.x == 0 );
178     assert( dtr.glyph.pos.y == -5 );
179     assert( dtr.pos.x == 4 );
180     assert( dtr.pos.y == 8 );
181     auto np = DiGlyphParam( DiGlyphParam.Flag.STRIKED ); 
182     dtr.param = np;
183     assert( dtr.param.flag == DiGlyphParam.Flag.STRIKED );
184 
185     dtr.draw();
186     assert( screen == im );
187 }