Checks if a UTF-8 codepoint should be counted as part of a word for Focus Reading
| 219 | |
| 220 | // Checks if a UTF-8 codepoint should be counted as part of a word for Focus Reading |
| 221 | bool isWordCharacter(uint32_t cp) { |
| 222 | // ASCII range (Catches 95%+ of characters immediately) |
| 223 | if (cp < 128) { |
| 224 | // Bitwise trick: (cp | 0x20) converts uppercase ASCII to lowercase. |
| 225 | // This checks for A-Z and a-z mathematically, avoiding memory lookups and <cctype> |
| 226 | return ((cp | 0x20) >= 'a' && (cp | 0x20) <= 'z') || cp == '\''; |
| 227 | } |
| 228 | |
| 229 | // General Punctuation Block, Currency, Math, Arrows, & Symbols (0x2000 - 0x2BFF) |
| 230 | if (cp >= 0x2000 && cp <= 0x2BFF) { |
| 231 | // Explicitly allow smart quotes, reject all other general punctuation (em-dashes, etc.) |
| 232 | return cp == 0x2018 || cp == 0x2019; |
| 233 | } |
| 234 | |
| 235 | // Latin-1 Punctuation Block (0x00A1 - 0x00BF) |
| 236 | if (cp >= 0x00A1 && cp <= 0x00BF) { |
| 237 | // Allow ordinal indicators and micro sign, reject the rest (¡, ¿, «, », etc.) |
| 238 | return cp == 0x00AA || cp == 0x00B5 || cp == 0x00BA; |
| 239 | } |
| 240 | |
| 241 | // Rejects Two-em dash, Three-em dash, Double oblique hyphen, etc. |
| 242 | if (cp >= 0x2E00 && cp <= 0x2E7F) return false; |
| 243 | |
| 244 | // Rejects Modifier Minus (0x02D7), Small Hyphen (0xFE63), and Fullwidth Hyphen (0xFF0D) |
| 245 | if (cp == 0x02D7 || cp == 0xFE63 || cp == 0xFF0D) return false; |
| 246 | // Assume all other Unicode ranges (accented letters, Cyrillic, Greek, etc.) are valid |
| 247 | |
| 248 | return true; |
| 249 | } |
| 250 | |
| 251 | } // namespace |
| 252 |