1+ /*
2+ * Copyright (c) 2026 ThorVG project. All rights reserved.
3+
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+
11+ * The above copyright notice and this permission notice shall be included in all
12+ * copies or substantial portions of the Software.
13+
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+ * SOFTWARE.
21+ */
22+
23+ #include " Example.h"
24+
25+ /* ***********************************************************************/
26+ /* ThorVG Drawing Contents */
27+ /* ***********************************************************************/
28+
29+ struct UserExample : tvgexam::Example
30+ {
31+ bool content (tvg::Canvas* canvas, uint32_t w, uint32_t h) override
32+ {
33+ // Background
34+ auto shape = tvg::Shape::gen ();
35+ shape->appendRect (0 , 0 , w, h);
36+ shape->fill (75 , 75 , 75 );
37+ canvas->add (shape);
38+
39+ // Load a necessary font data.
40+ // The loaded font will be released when the Initializer::term() is called.
41+ // Otherwise, you can immediately unload the font data.
42+ // Please check Text::unload() APIs.
43+ if (!tvgexam::verify (tvg::Text::load (EXAMPLE_DIR" /font/DMSans.otf" ))) return false ;
44+ if (!tvgexam::verify (tvg::Text::load (EXAMPLE_DIR" /font/Pretendard.otf" ))) return false ;
45+ if (!tvgexam::verify (tvg::Text::load (EXAMPLE_DIR" /font/NanumGothicCoding.otf" ))) return false ;
46+
47+ // Load from memory
48+ ifstream file (EXAMPLE_DIR" /font/SentyCloud.otf" , ios::binary);
49+ if (!file.is_open ()) return false ;
50+ file.seekg (0 , std::ios::end);
51+ auto size = file.tellg ();
52+ file.seekg (0 , std::ios::beg);
53+ auto data = (char *)malloc (size);
54+ if (data && file.read (data, size)) {
55+ if (!tvgexam::verify (tvg::Text::load (" SentyCloud" , data, size, " otf" , true ))) return false ;
56+ }
57+ file.close ();
58+ free (data);
59+
60+ auto text = tvg::Text::gen ();
61+ text->font (" DMSans" );
62+ text->size (60 );
63+ text->text (" THORVG OpenType Font" );
64+ text->fill (255 , 255 , 255 );
65+ canvas->add (text);
66+
67+ auto text2 = tvg::Text::gen ();
68+ text2->font (" DMSans" );
69+ text2->size (30 );
70+ text2->italic ();
71+ text2->text (" Font = \" DMSans\" , Size = 30, Style = Italic" );
72+ text2->translate (0 , 120 );
73+ text2->fill (255 , 255 , 255 );
74+ canvas->add (text2);
75+
76+ auto text3 = tvg::Text::gen ();
77+ text3->font (nullptr ); // Use any font
78+ text3->size (40 );
79+ text3->text (" Kerning Test: VA, AV, TJ, JT" );
80+ text3->fill (255 , 255 , 255 );
81+ text3->translate (0 , 195 );
82+ canvas->add (text3);
83+
84+ auto text4 = tvg::Text::gen ();
85+ text4->font (" DMSans" );
86+ text4->size (25 );
87+ text4->text (" Purple Text" );
88+ text4->fill (255 , 0 , 255 );
89+ text4->translate (0 , 280 );
90+ canvas->add (text4);
91+
92+ auto text5 = tvg::Text::gen ();
93+ text5->font (" DMSans" );
94+ text5->size (25 );
95+ text5->text (" Gray Text" );
96+ text5->fill (150 , 150 , 150 );
97+ text5->translate (220 , 280 );
98+ canvas->add (text5);
99+
100+ auto text6 = tvg::Text::gen ();
101+ text6->font (" DMSans" );
102+ text6->size (25 );
103+ text6->text (" Yellow Text" );
104+ text6->fill (255 , 255 , 0 );
105+ text6->translate (400 , 280 );
106+ canvas->add (text6);
107+
108+ auto text7 = tvg::Text::gen ();
109+ text7->font (" Pretendard" );
110+ text7->size (15 );
111+ text7->text (" Transformed Text - 30'" );
112+ text7->fill (0 , 0 , 0 );
113+ text7->translate (600 , 370 );
114+ text7->rotate (30 );
115+ canvas->add (text7);
116+
117+ auto text8 = tvg::Text::gen ();
118+ text8->font (" Pretendard" );
119+ text8->size (15 );
120+ text8->fill (0 , 0 , 0 );
121+ text8->text (" Transformed Text - 90'" );
122+ text8->translate (600 , 370 );
123+ text8->rotate (90 );
124+ canvas->add (text8);
125+
126+ auto text9 = tvg::Text::gen ();
127+ text9->font (" Pretendard" );
128+ text9->size (15 );
129+ text9->fill (0 , 0 , 0 );
130+ text9->text (" Transformed Text - 180'" );
131+ text9->translate (800 , 370 );
132+ text9->rotate (180 );
133+ canvas->add (text9);
134+
135+ // gradient texts
136+ float x, y, w2, h2;
137+
138+ auto text10 = tvg::Text::gen ();
139+ text10->font (" Pretendard" );
140+ text10->size (50 );
141+ text10->text (" Linear Text" );
142+ text10->bounds (&x, &y, &w2, &h2);
143+
144+ // LinearGradient
145+ auto fill = tvg::LinearGradient::gen ();
146+ fill->linear (x, y + h2 * 0 .5f , x + w2, y + h2 * 0 .5f );
147+
148+ // Gradient Color Stops
149+ tvg::Fill::ColorStop colorStops[3 ];
150+ colorStops[0 ] = {0 , 255 , 0 , 0 , 255 };
151+ colorStops[1 ] = {0.5 , 255 , 255 , 0 , 255 };
152+ colorStops[2 ] = {1 , 255 , 255 , 255 , 255 };
153+ fill->colorStops (colorStops, 3 );
154+ text10->fill (fill);
155+ text10->translate (0 , 320 );
156+
157+ canvas->add (text10);
158+
159+ auto text11 = tvg::Text::gen ();
160+ text11->font (" NanumGothicCoding" );
161+ text11->size (40 );
162+ text11->text (" \xeb\x82\x98\xeb\x88\x94\xea\xb3\xa0\xeb\x94\x95\xec\xbd\x94\xeb\x94\xa9\x28\x55\x54\x46\x2d\x38\x29 " );
163+ text11->bounds (&x, &y, &w2, &h2);
164+
165+ // RadialGradient
166+ auto fill2 = tvg::RadialGradient::gen ();
167+ fill2->radial (x + w2 * 0 .5f , y + h2 * 0 .5f , w2 * 0 .5f , x + w2 * 0 .5f , y + h2 * 0 .5f , 0 .0f );
168+
169+ // Gradient Color Stops
170+ tvg::Fill::ColorStop colorStops2[3 ];
171+ colorStops2[0 ] = {0 , 0 , 255 , 255 , 255 };
172+ colorStops2[1 ] = {0.5 , 255 , 255 , 0 , 255 };
173+ colorStops2[2 ] = {1 , 255 , 255 , 255 , 255 };
174+
175+ fill2->colorStops (colorStops2, 3 );
176+
177+ text11->fill (fill2);
178+ text11->translate (0 , 420 );
179+
180+ canvas->add (text11);
181+
182+ auto text12 = tvg::Text::gen ();
183+ text12->font (" SentyCloud" );
184+ text12->size (50 );
185+ text12->fill (255 , 25 , 25 );
186+ text12->outline (3 , 255 , 200 , 200 );
187+ text12->text (" \xe4\xb8\x8d\xe5\x88\xb0\xe9\x95\xbf\xe5\x9f\x8e\xe9\x9d\x9e\xe5\xa5\xbd\xe6\xb1\x89\xef\xbc\x81 " );
188+ text12->translate (0 , 495 );
189+ canvas->add (text12);
190+
191+ auto text13 = tvg::Text::gen ();
192+ text13->font (" DMSans" );
193+ text13->size (20 );
194+ text13->fill (255 , 255 , 255 );
195+ text13->text (" LINE-FEED TEST. THIS IS THE FIRST LINE - \n THIS IS THE SECOND LINE." );
196+ text13->translate (0 , 595 );
197+ canvas->add (text13);
198+
199+ auto text14 = tvg::Text::gen ();
200+ text14->font (" DMSans" );
201+ text14->size (20 );
202+ text14->fill (255 , 255 , 255 );
203+ text14->spacing (1 .5f , 1 .5f );
204+ text14->text (" 1.5x SPACING TEST. THIS IS THE FIRST LINE - \n THIS IS THE SECOND LINE." );
205+ text14->translate (0 , 670 );
206+ canvas->add (text14);
207+
208+ return true ;
209+ }
210+ };
211+
212+
213+ /* ***********************************************************************/
214+ /* Entry Point */
215+ /* ***********************************************************************/
216+
217+ int main (int argc, char **argv)
218+ {
219+ return tvgexam::main (new UserExample, argc, argv, false , 1024 , 1024 );
220+ }
0 commit comments