| 183 | } |
| 184 | |
| 185 | Rect Text::GetSize(const Font& font, std::string_view text) { |
| 186 | Rect rect; |
| 187 | Rect rect_tmp; |
| 188 | |
| 189 | auto iter = text.data(); |
| 190 | const auto end = iter + text.size(); |
| 191 | |
| 192 | if (font.CanShape()) { |
| 193 | std::u32string text32; |
| 194 | while (iter != end) { |
| 195 | auto ret = Utils::TextNext(iter, end, 0); |
| 196 | |
| 197 | iter = ret.next; |
| 198 | if (EP_UNLIKELY(!ret)) { |
| 199 | continue; |
| 200 | } |
| 201 | |
| 202 | if (EP_UNLIKELY(Utils::IsControlCharacter(ret.ch))) { |
| 203 | rect_tmp = GetSize(font, ret.ch, ret.is_exfont); |
| 204 | rect.width += rect_tmp.width; |
| 205 | rect.height = std::max(rect.height, rect_tmp.height); |
| 206 | continue; |
| 207 | } |
| 208 | |
| 209 | if (ret.is_exfont) { |
| 210 | if (!text32.empty()) { |
| 211 | auto shape_ret = font.Shape(text32); |
| 212 | text32.clear(); |
| 213 | |
| 214 | for (const auto& ch: shape_ret) { |
| 215 | Rect size = font.GetSize(ch); |
| 216 | rect.width += ch.offset.x + size.width; |
| 217 | rect.height = std::max(rect.height, size.height); |
| 218 | } |
| 219 | } |
| 220 | |
| 221 | rect_tmp = GetSize(font, ret.ch, ret.is_exfont); |
| 222 | rect.width += rect_tmp.width; |
| 223 | rect.height = std::max(rect.height, rect_tmp.height); |
| 224 | continue; |
| 225 | } |
| 226 | |
| 227 | text32 += ret.ch; |
| 228 | } |
| 229 | |
| 230 | if (!text32.empty()) { |
| 231 | auto shape_ret = font.Shape(text32); |
| 232 | |
| 233 | for (const auto& ch: shape_ret) { |
| 234 | Rect size = font.GetSize(ch); |
| 235 | rect.width += ch.offset.x + size.width; |
| 236 | rect.height = std::max(rect.height, size.height); |
| 237 | } |
| 238 | } |
| 239 | } else { |
| 240 | while (iter != end) { |
| 241 | auto ret = Utils::TextNext(iter, end, 0); |
| 242 |
no test coverage detected