@@ -109,4 +109,80 @@ namespace pimoroni {
109
109
110
110
return Point (caret.x , caret.y );
111
111
}
112
+
113
+ Point PicoVector::text (std::string_view text, Point origin, float angle) {
114
+ // TODO: Normalize types somehow, so we're not converting?
115
+ pretty_poly::point_t <float > caret (0 , 0 );
116
+
117
+ // Prepare a transformation matrix for character and offset rotation
118
+ angle = 2 * M_PI * (angle / 360 .0f );
119
+ pretty_poly::mat3_t transform = pretty_poly::mat3_t::rotation (angle);
120
+
121
+ // Align text from the bottom left
122
+ caret.y += text_metrics.line_height ;
123
+ caret *= transform;
124
+
125
+ pretty_poly::point_t <float > space;
126
+ pretty_poly::point_t <float > carriage_return (0 , text_metrics.line_height );
127
+
128
+ space.x = alright_fonts::measure_character (text_metrics, ' ' ).w ;
129
+ if (space.x == 0 ) {
130
+ space.x = text_metrics.word_spacing ;
131
+ }
132
+
133
+ space *= transform;
134
+ carriage_return *= transform;
135
+
136
+ size_t i = 0 ;
137
+
138
+ while (i < text.length ()) {
139
+ size_t next_space = text.find (' ' , i + 1 );
140
+
141
+ if (next_space == std::string::npos) {
142
+ next_space = text.length ();
143
+ }
144
+
145
+ size_t next_linebreak = text.find (' \n ' , i + 1 );
146
+
147
+ if (next_linebreak == std::string::npos) {
148
+ next_linebreak = text.length ();
149
+ }
150
+
151
+ size_t next_break = std::min (next_space, next_linebreak);
152
+
153
+ uint16_t word_width = 0 ;
154
+ for (size_t j = i; j < next_break; j++) {
155
+ word_width += alright_fonts::measure_character (text_metrics, text[j]).w ;
156
+ word_width += text_metrics.letter_spacing ;
157
+ }
158
+
159
+ if (caret.x != 0 && caret.x + word_width > graphics->clip .w ) {
160
+ caret -= carriage_return;
161
+ carriage_return.x = 0 ;
162
+ }
163
+
164
+ for (size_t j = i; j < std::min (next_break + 1 , text.length ()); j++) {
165
+ if (text[j] == ' \n ' ) { // Linebreak
166
+ caret -= carriage_return;
167
+ carriage_return.x = 0 ;
168
+ } else if (text[j] == ' ' ) { // Space
169
+ caret += space;
170
+ carriage_return += space;
171
+ } else {
172
+ alright_fonts::render_character (text_metrics, text[j], pretty_poly::point_t <int >(origin.x + caret.x , origin.y + caret.y ), transform);
173
+ }
174
+ pretty_poly::point_t <float > advance (
175
+ alright_fonts::measure_character (text_metrics, text[j]).w + text_metrics.letter_spacing ,
176
+ 0
177
+ );
178
+ advance *= transform;
179
+ caret += advance;
180
+ carriage_return += advance;
181
+ }
182
+
183
+ i = next_break + 1 ;
184
+ }
185
+
186
+ return Point (caret.x , caret.y );
187
+ }
112
188
}
0 commit comments