## Summary This PR introduces **Focus Reading**, a generic implementation of artificial fixation points (similar to Bionic Reading) designed to improve reading speed and focus by bolding the initial characters of words. This is achieved by dynamically bolding characters during indexing. <img width="500" alt="Focus Reading on X3" src="https://github.com/user-attachments/assets/94a632a5-82da-47be-957c-538b35bf84d9" /> ### Implementation Details #### Core Text Engine (`ParsedText`) - Modified `ParsedText::addWord` to implement a custom bolding algorithm. It uses a 45% ratio for bolding, with a minimum of 1 character and a maximum of 9. - UTF-8 Safety: Integrated `utf8NextCodepoint` to ensure character counting and string slicing occur at safe byte boundaries, preventing corruption of multi-byte characters (e.g., accented letters or smart quotes). - Intelligent Tokenization: This correctly identifies and separates "word" characters (letters, apostrophes, hyphens) from "non-word" characters (numbers, brackets, smart quotes). - Formatting Preservation: The logic ensures that punctuation is not "stolen" for the bolding count and that existing styles (like italics or underlines) are preserved across the bold/regular split. - Processing at indexing stage reduces CPU load at render-time and ensures layout/fit is unaffected. - Split details are tracked with `wordIsFocusSuffix`. After splitting and layout, suffixes are merged back into their preceding word entries to prevent a doubling of RAM usage. #### Settings and UI - Version Management: Bumped `SECTION_FILE_VERSION` to `21` - Global Settings: Added `focusReadingEnabled` to `CrossPointSettings`. - User Interface: Added a new toggle in the "Reader" section of the settings menu, positioned after the "Embedded Style" option. - Localization: Added the `STR_FOCUS_READING` string #### Plumbing - Plumbed the `focusReadingEnabled` boolean through `EpubReaderActivity`, `Section`, and `ChapterHtmlSlimParser` to ensure the user's setting reaches the `ParsedText` constructor during chapter indexing. ## Additional Context ### Files Changed - `lib/Epub/Epub/ParsedText.h / .cpp`: Core fixation logic and UTF-8 tokenization. - `lib/Epub/Epub/Section.h / .cpp`: Cache header updates and invalidation logic. - `lib/Epub/Epub/parsers/ChapterHtmlSlimParser.h / .cpp`: Plumbing the setting to text blocks. - `src/CrossPointSettings.h`: Data persistence for the new setting. - `src/SettingsList.h`: UI toggle implementation. - `src/activities/reader/EpubReaderActivity.cpp`: Handling settings changes during reading sessions. - `lib/I18n/translations/*.yaml`: UI strings. --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**YES**_
299 lines
11 KiB
YAML
299 lines
11 KiB
YAML
_language_name: "Türkçe"
|
||
_language_code: "TR"
|
||
_order: "17"
|
||
|
||
STR_CROSSPOINT: "CrossPoint"
|
||
STR_BOOTING: "BAŞLATILIYOR"
|
||
STR_SLEEPING: "UYKU MODU"
|
||
STR_ENTERING_SLEEP: "Uyku moduna geçiliyor"
|
||
STR_BROWSE_FILES: "Dosyalara Göz At"
|
||
STR_FILE_TRANSFER: "Dosya Transferi"
|
||
STR_SETTINGS_TITLE: "Ayarlar"
|
||
STR_CONTINUE_READING: "Okumaya Devam Et"
|
||
STR_NO_OPEN_BOOK: "Açık kitap yok"
|
||
STR_START_READING: "Aşağıdan okumaya başlayın"
|
||
STR_SELECT_CHAPTER: "Bölüm Seç"
|
||
STR_NO_CHAPTERS: "Bölüm yok"
|
||
STR_END_OF_BOOK: "Kitabın sonu"
|
||
STR_EMPTY_CHAPTER: "Boş bölüm"
|
||
STR_INDEXING: "Endeksleniyor"
|
||
STR_MEMORY_ERROR: "Bellek hatası"
|
||
STR_PAGE_LOAD_ERROR: "Sayfa yükleme hatası"
|
||
STR_EMPTY_FILE: "Boş dosya"
|
||
STR_OUT_OF_BOUNDS: "Sınırların dışında"
|
||
STR_LOADING: "Yükleniyor..."
|
||
STR_LOADING_POPUP: "Yükleniyor"
|
||
STR_WIFI_NETWORKS: "WiFi Ağları"
|
||
STR_NO_NETWORKS: "Ağ bulunamadı"
|
||
STR_NETWORKS_FOUND: "%zu ağ bulundu"
|
||
STR_SCANNING: "Tarıyor..."
|
||
STR_CONNECTING: "Bağlanıyor..."
|
||
STR_CONNECTED: "Bağlandı!"
|
||
STR_CONNECTION_FAILED: "Bağlantı Başarısız"
|
||
STR_FORGET_NETWORK: "Ağı Unut?"
|
||
STR_SAVE_PASSWORD: "Şifre kaydedilsin mi?"
|
||
STR_PRESS_OK_SCAN: "Tekrar taramak için OK'e basın"
|
||
STR_JOIN_NETWORK: "Bir Ağa Katıl"
|
||
STR_CREATE_HOTSPOT: "Erişim Noktası Oluştur"
|
||
STR_JOIN_DESC: "Mevcut bir WiFi ağına bağlan"
|
||
STR_HOTSPOT_DESC: "Başkalarının katılabileceği ağ oluştur"
|
||
STR_STARTING_HOTSPOT: "Erişim Noktası Başlatılıyor..."
|
||
STR_HOTSPOT_MODE: "Erişim Noktası Modu"
|
||
STR_CONNECT_WIFI_HINT: "Cihazınızı bu WiFi ağına bağlayın"
|
||
STR_OPEN_URL_HINT: "Tarayıcınızda bu adresi açın"
|
||
STR_OR_HTTP_PREFIX: "veya http://"
|
||
STR_SCAN_QR_HINT: "veya telefonunuzla QR kodu tarayın:"
|
||
STR_CALIBRE_WIRELESS: "Calibre Kablosuz"
|
||
STR_CALIBRE_WEB_URL: "OPDS URL"
|
||
STR_NETWORK_LEGEND: "* = Şifreli | + = Kayıtlı"
|
||
STR_MAC_ADDRESS: "MAC adresi:"
|
||
STR_CHECKING_WIFI: "WiFi kontrol ediliyor..."
|
||
STR_ENTER_WIFI_PASSWORD: "WiFi Şifresini Girin"
|
||
STR_TO_PREFIX: "Ağ: "
|
||
STR_CALIBRE_RECEIVING: "Alınıyor: "
|
||
STR_CALIBRE_RECEIVED: "Alındı: "
|
||
STR_CALIBRE_INSTRUCTION_1: "1) CrossPoint Reader eklentisini kurun"
|
||
STR_CALIBRE_INSTRUCTION_2: "2) Aynı WiFi ağında olun"
|
||
STR_CALIBRE_INSTRUCTION_3: "3) Calibre'de: \"Cihaza gönder\""
|
||
STR_CALIBRE_INSTRUCTION_4: "\"Gönderim sırasında bu ekranı açık tutun\""
|
||
STR_CAT_DISPLAY: "Ekran"
|
||
STR_CAT_READER: "Okuyucu"
|
||
STR_CAT_CONTROLS: "Kontroller"
|
||
STR_CAT_SYSTEM: "Sistem"
|
||
STR_SLEEP_SCREEN: "Uyku Ekranı"
|
||
STR_SLEEP_COVER_MODE: "Uyku Ekranı Kapak Modu"
|
||
STR_HIDE_BATTERY: "Pil Yüzdesini Gizle"
|
||
STR_EXTRA_SPACING: "Ekstra Paragraf Boşluğu"
|
||
STR_TEXT_AA: "Metin Yumuşatma (AA)"
|
||
STR_SHORT_PWR_BTN: "Kısa Güç Tuşu Tıklaması"
|
||
STR_ORIENTATION: "Okuma Yönü"
|
||
STR_SIDE_BTN_LAYOUT: "Yan Tuş Dizilimi (okuyucu)"
|
||
STR_LONG_PRESS_BEHAVIOR: "Long-press button behavior"
|
||
STR_LONG_PRESS_BEHAVIOR_OFF: "OFF"
|
||
STR_LONG_PRESS_BEHAVIOR_SKIP: "Chapter skip"
|
||
STR_LONG_PRESS_BEHAVIOR_ORIENTATION: "Orientation change"
|
||
STR_FONT_FAMILY: "Okuyucu Yazı Tipi Ailesi"
|
||
STR_FONT_SIZE: "Arayüz Yazı Boyutu"
|
||
STR_LINE_SPACING: "Okuyucu Satır Aralığı"
|
||
STR_SCREEN_MARGIN: "Okuyucu Ekran Kenar Boşluğu"
|
||
STR_PARA_ALIGNMENT: "Okuyucu Paragraf Hizalaması"
|
||
STR_HYPHENATION: "Hecelerden Ayırma"
|
||
STR_TIME_TO_SLEEP: "Uykuya Geçme Süresi"
|
||
STR_SHOW_HIDDEN_FILES: "Gizli Dosyaları Göster"
|
||
STR_REFRESH_FREQ: "Yenileme Sıklığı"
|
||
STR_KOREADER_SYNC: "KOReader Senkronizasyonu"
|
||
STR_CHECK_UPDATES: "Güncellemeleri denetle"
|
||
STR_LANGUAGE: "Dil"
|
||
STR_CLEAR_READING_CACHE: "Okuma Önbelleğini Temizle"
|
||
STR_USERNAME: "Kullanıcı Adı"
|
||
STR_PASSWORD: "Şifre"
|
||
STR_SYNC_SERVER_URL: "Senkronizasyon Sunucu Adresi"
|
||
STR_DOCUMENT_MATCHING: "Belge Eşleştirme"
|
||
STR_AUTHENTICATE: "Kimlik Doğrula"
|
||
STR_KOREADER_USERNAME: "KOReader Kullanıcı Adı"
|
||
STR_KOREADER_PASSWORD: "KOReader Şifresi"
|
||
STR_FILENAME: "Dosya Adı"
|
||
STR_BINARY: "İkili"
|
||
STR_SET_CREDENTIALS_FIRST: "Önce kimlik bilgilerini ayarlayın"
|
||
STR_WIFI_CONN_FAILED: "WiFi bağlantısı başarısız"
|
||
STR_AUTHENTICATING: "Kimlik doğrulanıyor..."
|
||
STR_AUTH_SUCCESS: "Kimlik doğrulama başarılı!"
|
||
STR_KOREADER_AUTH: "KOReader Doğrulaması"
|
||
STR_SYNC_READY: "KOReader senkronizasyonu hazır"
|
||
STR_AUTH_FAILED: "Kimlik Doğrulama Başarısız"
|
||
STR_DONE: "Tamamlandı"
|
||
STR_CLEAR_CACHE_WARNING_1: "Bu işlem tüm önbelleğe alınmış verileri siler."
|
||
STR_CLEAR_CACHE_WARNING_2: "Tüm okuma ilerlemesi kaybolacak!"
|
||
STR_CLEAR_CACHE_WARNING_3: "Kitapların tekrar açıldığında yeniden"
|
||
STR_CLEAR_CACHE_WARNING_4: "endekslenmesi gerekecek."
|
||
STR_CLEARING_CACHE: "Önbellek temizleniyor..."
|
||
STR_CACHE_CLEARED: "Önbellek Temizlendi"
|
||
STR_ITEMS_REMOVED: "öğe kaldırıldı"
|
||
STR_FAILED_LOWER: "başarısız"
|
||
STR_CLEAR_CACHE_FAILED: "Önbellek temizlenemedi"
|
||
STR_CHECK_SERIAL_OUTPUT: "Detaylar için seri çıktıya bakın"
|
||
STR_DARK: "Koyu"
|
||
STR_LIGHT: "Açık"
|
||
STR_CUSTOM: "Özel"
|
||
STR_COVER: "Kapak"
|
||
STR_NONE_OPT: "Yok"
|
||
STR_FIT: "Sığdır"
|
||
STR_CROP: "Kırp"
|
||
STR_NEVER: "Asla"
|
||
STR_IN_READER: "Okuyucuda"
|
||
STR_ALWAYS: "Her Zaman"
|
||
STR_IGNORE: "Yoksay"
|
||
STR_SLEEP: "Uyku"
|
||
STR_PAGE_TURN: "Sayfa Çevirme"
|
||
STR_PORTRAIT: "Dikey"
|
||
STR_LANDSCAPE_CW: "Yatay (Saat Yönü)"
|
||
STR_INVERTED: "Ters"
|
||
STR_LANDSCAPE_CCW: "Yatay (Saat Yönü Tersi)"
|
||
STR_PREV_NEXT: "Önceki/Sonraki"
|
||
STR_NEXT_PREV: "Sonraki/Önceki"
|
||
STR_NOTO_SERIF: "Noto Serif"
|
||
STR_NOTO_SANS: "Noto Sans"
|
||
STR_OPEN_DYSLEXIC: "Open Dyslexic"
|
||
STR_SMALL: "Küçük"
|
||
STR_MEDIUM: "Orta"
|
||
STR_LARGE: "Büyük"
|
||
STR_X_LARGE: "Çok Büyük"
|
||
STR_TIGHT: "Dar"
|
||
STR_NORMAL: "Normal"
|
||
STR_WIDE: "Geniş"
|
||
STR_JUSTIFY: "İki Yana Yasla"
|
||
STR_ALIGN_LEFT: "Sola Yasla"
|
||
STR_CENTER: "Ortala"
|
||
STR_ALIGN_RIGHT: "Sağa Yasla"
|
||
STR_MIN_1: "1 dak"
|
||
STR_MIN_5: "5 dak"
|
||
STR_MIN_10: "10 dak"
|
||
STR_MIN_15: "15 dak"
|
||
STR_MIN_30: "30 dak"
|
||
STR_PAGES_1: "1 sayfa"
|
||
STR_PAGES_5: "5 sayfa"
|
||
STR_PAGES_10: "10 sayfa"
|
||
STR_PAGES_15: "15 sayfa"
|
||
STR_PAGES_30: "30 sayfa"
|
||
STR_UPDATE: "Güncelle"
|
||
STR_CHECKING_UPDATE: "Güncelleme denetleniyor..."
|
||
STR_NEW_UPDATE: "Yeni güncelleme mevcut!"
|
||
STR_CURRENT_VERSION: "Mevcut Sürüm: "
|
||
STR_NEW_VERSION: "Yeni Sürüm: "
|
||
STR_UPDATING: "Güncelleniyor..."
|
||
STR_NO_UPDATE: "Güncelleme yok"
|
||
STR_UPDATE_FAILED: "Güncelleme başarısız"
|
||
STR_UPDATE_COMPLETE: "Güncelleme tamamlandı"
|
||
STR_POWER_ON_HINT: "Açmak için güç tuşuna basılı tutun"
|
||
STR_NO_ENTRIES: "Girdi bulunamadı"
|
||
STR_DOWNLOADING: "İndiriliyor..."
|
||
STR_DOWNLOAD_FAILED: "İndirme başarısız"
|
||
STR_ERROR_MSG: "Hata:"
|
||
STR_UNNAMED: "İsimsiz"
|
||
STR_NO_SERVER_URL: "Sunucu adresi ayarlanmamış"
|
||
STR_FETCH_FEED_FAILED: "Akış alınamadı"
|
||
STR_PARSE_FEED_FAILED: "Akış ayrıştırılamadı"
|
||
STR_NETWORK_PREFIX: "Ağ: "
|
||
STR_IP_ADDRESS_PREFIX: "IP Adresi: "
|
||
STR_ERROR_GENERAL_FAILURE: "Hata: Genel hata"
|
||
STR_ERROR_NETWORK_NOT_FOUND: "Hata: Ağ bulunamadı"
|
||
STR_ERROR_CONNECTION_TIMEOUT: "Hata: Bağlantı zaman aşımı"
|
||
STR_SD_CARD: "SD kart"
|
||
STR_BACK: "« Geri"
|
||
STR_EXIT: "« Çıkış"
|
||
STR_HOME: "« Ana Sayfa"
|
||
STR_SELECT: "Seç"
|
||
STR_TOGGLE: "Değiştir"
|
||
STR_CONFIRM: "Onayla"
|
||
STR_CANCEL: "İptal"
|
||
STR_CONNECT: "Bağlan"
|
||
STR_OPEN: "Aç"
|
||
STR_DOWNLOAD: "İndir"
|
||
STR_RETRY: "Tekrar Dene"
|
||
STR_YES: "Evet"
|
||
STR_NO: "Hayır"
|
||
STR_STATE_ON: "AÇIK"
|
||
STR_STATE_OFF: "KAPALI"
|
||
STR_NOT_SET: "Ayarlanmadı"
|
||
STR_DIR_LEFT: "Sol"
|
||
STR_DIR_RIGHT: "Sağ"
|
||
STR_DIR_UP: "Yukarı"
|
||
STR_DIR_DOWN: "Aşağı"
|
||
STR_OK_BUTTON: "Tamam"
|
||
STR_SLEEP_COVER_FILTER: "Uyku Ekranı Kapak Filtresi"
|
||
STR_FILTER_CONTRAST: "Kontrast"
|
||
STR_UI_THEME: "Arayüz Teması"
|
||
STR_THEME_CLASSIC: "Klasik"
|
||
STR_THEME_LYRA: "Lyra"
|
||
STR_THEME_LYRA_EXTENDED: "Lyra Genişletilmiş"
|
||
STR_SUNLIGHT_FADING_FIX: "Güneş Işığı Solma Düzeltmesi"
|
||
STR_REMAP_FRONT_BUTTONS: "Ön Tuşları Yeniden Ata"
|
||
STR_OPDS_BROWSER: "OPDS Tarayıcı"
|
||
STR_COVER_CUSTOM: "Kapak + Özel"
|
||
STR_MENU_RECENT_BOOKS: "Son Kitaplar"
|
||
STR_NO_RECENT_BOOKS: "Son okunan kitap yok"
|
||
STR_CALIBRE_DESC: "Calibre kablosuz cihaz transferini kullan"
|
||
STR_FORGET_AND_REMOVE: "Ağı unut ve kayıtlı şifreyi sil?"
|
||
STR_FORGET_BUTTON: "Unut"
|
||
STR_CALIBRE_STARTING: "Calibre Başlatılıyor..."
|
||
STR_CALIBRE_SETUP: "Kurulum"
|
||
STR_CALIBRE_STATUS: "Durum"
|
||
STR_CLEAR_BUTTON: "Temizle"
|
||
STR_DEFAULT_VALUE: "Varsayılan"
|
||
STR_REMAP_PROMPT: "Her rol için bir ön tuşa basın"
|
||
STR_UNASSIGNED: "Atanmamış"
|
||
STR_ALREADY_ASSIGNED: "Zaten atanmış"
|
||
STR_REMAP_RESET_HINT: "Yan tuş Yukarı: Varsayılan dizilime dön"
|
||
STR_REMAP_CANCEL_HINT: "Yan tuş Aşağı: Atamayı iptal et"
|
||
STR_HW_BACK_LABEL: "Geri (1. tuş)"
|
||
STR_HW_CONFIRM_LABEL: "Onayla (2. tuş)"
|
||
STR_HW_LEFT_LABEL: "Sol (3. tuş)"
|
||
STR_HW_RIGHT_LABEL: "Sağ (4. tuş)"
|
||
STR_GO_TO_PERCENT: "%'ye git"
|
||
STR_GO_HOME_BUTTON: "Ana Sayfaya Git"
|
||
STR_SYNC_PROGRESS: "Okuma İlerlemesini Senkronize Et"
|
||
STR_DELETE_CACHE: "Kitap Önbelleğini Sil"
|
||
STR_CHAPTER_PREFIX: "Bölüm: "
|
||
STR_PAGES_SEPARATOR: " sayfa | "
|
||
STR_BOOK_PREFIX: "Kitap: "
|
||
STR_CALIBRE_URL_HINT: "Calibre için URL'nize /opds ekleyin"
|
||
STR_PERCENT_STEP_HINT: "Sol/Sağ: %1 Yukarı/Aşağı: %10"
|
||
STR_SYNCING_TIME: "Zaman senkronize ediliyor..."
|
||
STR_CALC_HASH: "Belge özeti hesaplanıyor..."
|
||
STR_HASH_FAILED: "Belge özeti hesaplanamadı"
|
||
STR_FETCH_PROGRESS: "Uzak ilerleme alınıyor..."
|
||
STR_UPLOAD_PROGRESS: "İlerleme yükleniyor..."
|
||
STR_NO_CREDENTIALS_MSG: "Kimlik bilgisi ayarlanmamış"
|
||
STR_KOREADER_SETUP_HINT: "Ayarlar'da KOReader hesabını kurun"
|
||
STR_PROGRESS_FOUND: "İlerleme bulundu!"
|
||
STR_REMOTE_LABEL: "Uzak:"
|
||
STR_LOCAL_LABEL: "Yerel:"
|
||
STR_PAGE_OVERALL_FORMAT: "Sayfa %d, genel %.2f%%"
|
||
STR_PAGE_TOTAL_OVERALL_FORMAT: "Sayfa %d/%d, genel %.2f%%"
|
||
STR_DEVICE_FROM_FORMAT: " Şuradan: %s"
|
||
STR_APPLY_REMOTE: "Uzak ilerlemeyi uygula"
|
||
STR_UPLOAD_LOCAL: "Yerel ilerlemeyi yükle"
|
||
STR_NO_REMOTE_MSG: "Uzak ilerleme bulunamadı"
|
||
STR_UPLOAD_PROMPT: "Mevcut konumu yükle?"
|
||
STR_UPLOAD_SUCCESS: "İlerleme yüklendi!"
|
||
STR_SYNC_FAILED_MSG: "Senkronizasyon başarısız"
|
||
STR_SAVE_PROGRESS_FAILED: "İlerleme kaydedilemedi"
|
||
STR_SECTION_PREFIX: "Bölüm "
|
||
STR_UPLOAD: "Yükle"
|
||
STR_BOOK_S_STYLE: "Kitabın Stili"
|
||
STR_EMBEDDED_STYLE: "Gömülü Stil"
|
||
STR_FOCUS_READING: "Odaklanmış Okuma"
|
||
STR_OPDS_SERVER_URL: "OPDS Sunucu Adresi"
|
||
STR_AUTO_TURN_ENABLED: "Otomatik Çevirme Etkin: "
|
||
STR_AUTO_TURN_PAGES_PER_MIN: "Otomatik Çevirme (Dakikada Sayfa)"
|
||
STR_BATTERY: "Pil"
|
||
STR_BOOK: "Kitap"
|
||
STR_BOOK_PROGRESS_PERCENTAGE: "Kitap İlerleme Yüzdesi"
|
||
STR_CHAPTER: "Bölüm"
|
||
STR_CHAPTER_PAGE_COUNT: "Bölüm Sayfa Sayısı"
|
||
STR_CUSTOMISE_STATUS_BAR: "Durum Çubuğunu Özelleştir"
|
||
STR_DELETE: "Sil"
|
||
STR_DISPLAY_QR: "Sayfayı QR olarak göster"
|
||
STR_EXAMPLE_BOOK: "Kitap Başlığı"
|
||
STR_EXAMPLE_CHAPTER: "Bölüm 21"
|
||
STR_FOOTNOTES: "Dipnotlar"
|
||
STR_HIDE: "Gizle"
|
||
STR_IMAGES: "Görseller"
|
||
STR_IMAGES_DISPLAY: "Göster"
|
||
STR_IMAGES_PLACEHOLDER: "Yer Tutucu"
|
||
STR_IMAGES_SUPPRESS: "Bastır"
|
||
STR_LINK: "[bağlantı]"
|
||
STR_NO_FILES_FOUND: "Dosya bulunamadı"
|
||
STR_NO_FOOTNOTES: "Bu sayfada dipnot yok"
|
||
STR_PREVIEW: "Önizleme"
|
||
STR_PROGRESS_BAR: "İlerleme Çubuğu"
|
||
STR_PROGRESS_BAR_MEDIUM: "Orta"
|
||
STR_PROGRESS_BAR_THICK: "Kalın"
|
||
STR_PROGRESS_BAR_THICKNESS: "İlerleme Çubuğu Kalınlığı"
|
||
STR_PROGRESS_BAR_THIN: "İnce"
|
||
STR_SCREENSHOT_BUTTON: "Ekran görüntüsü al"
|
||
STR_SELECTED: "Seçili"
|
||
STR_SHOW: "Göster"
|
||
STR_TITLE: "Başlık"
|
||
STR_TILT_PAGE_TURN: "Eğerek sayfa çevirme"
|