* Create a new layouter. * @param str The string to create the layout for. * @param maxw The maximum width. * @param fontsize The size of font to use. */
| 127 | * @param fontsize The size of font to use. |
| 128 | */ |
| 129 | Layouter::Layouter(std::string_view str, int maxw, FontSize fontsize) : string(str) |
| 130 | { |
| 131 | FontState state(TC_INVALID, fontsize); |
| 132 | |
| 133 | while (true) { |
| 134 | auto line_length = str.find_first_of('\n'); |
| 135 | auto str_line = str.substr(0, line_length); |
| 136 | |
| 137 | LineCacheItem &line = GetCachedParagraphLayout(str_line, state); |
| 138 | if (line.layout != nullptr) { |
| 139 | state = line.state_after; |
| 140 | line.layout->Reflow(); |
| 141 | } else { |
| 142 | /* Line is new, layout it */ |
| 143 | FontState old_state = state; |
| 144 | |
| 145 | #if defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ) |
| 146 | if (line.layout == nullptr) { |
| 147 | GetLayouter<ICUParagraphLayoutFactory>(line, str_line, state); |
| 148 | if (line.layout == nullptr) { |
| 149 | state = std::move(old_state); |
| 150 | } |
| 151 | } |
| 152 | #endif |
| 153 | |
| 154 | #ifdef WITH_UNISCRIBE |
| 155 | if (line.layout == nullptr) { |
| 156 | GetLayouter<UniscribeParagraphLayoutFactory>(line, str_line, state); |
| 157 | if (line.layout == nullptr) { |
| 158 | state = std::move(old_state); |
| 159 | } |
| 160 | } |
| 161 | #endif |
| 162 | |
| 163 | #ifdef WITH_COCOA |
| 164 | if (line.layout == nullptr) { |
| 165 | GetLayouter<CoreTextParagraphLayoutFactory>(line, str_line, state); |
| 166 | if (line.layout == nullptr) { |
| 167 | state = std::move(old_state); |
| 168 | } |
| 169 | } |
| 170 | #endif |
| 171 | |
| 172 | if (line.layout == nullptr) { |
| 173 | GetLayouter<FallbackParagraphLayoutFactory>(line, str_line, state); |
| 174 | } |
| 175 | } |
| 176 | |
| 177 | if (line.cached_width != maxw) { |
| 178 | /* First run or width has changed, so we need to go through the layouter. Lines are moved into a cache to |
| 179 | * be reused if the width is not changed. */ |
| 180 | line.cached_layout.clear(); |
| 181 | line.cached_width = maxw; |
| 182 | for (;;) { |
| 183 | auto l = line.layout->NextLine(maxw); |
| 184 | if (l == nullptr) break; |
| 185 | line.cached_layout.push_back(std::move(l)); |
| 186 | } |