bool CCaptionParser::GetLanguageCode(int LanguageTag, char *pCode) const { if (pCode == NULL) return false; int Index = GetLanguageIndex(LanguageTag); if (Index < 0) return false; ::CopyMemory(pCode, m_LanguageList[Index].LanguageCode, 4); return true; }
void SelectTranslation(const WCHAR *exePath=NULL) { LANGID langId = GetUserDefaultUILanguage(); int idx = GetLanguageIndex(langId); if (-1 == idx) { // try a neutral language if the specific sublanguage isn't available langId = MAKELANGID(PRIMARYLANGID(langId), SUBLANG_NEUTRAL); idx = GetLanguageIndex(langId); } if (-1 != idx) { gTranslationIdx = idx; plogf("sp: Detected language %s (%d)", gLanguages[idx / gTranslationsCount], idx); } // try to extract the language used by SumatraPDF ScopedMem<WCHAR> path; if (exePath) { path.Set(path::GetDir(exePath)); path.Set(path::Join(path, PREFS_FILE_NAME)); } if (!file::Exists(path)) { path.Set(GetSpecialFolder(CSIDL_APPDATA)); path.Set(path::Join(path, L"SumatraPDF\\" PREFS_FILE_NAME)); } if (!file::Exists(path)) return; plogf("sp: Found preferences at %S", path); ScopedMem<char> prefsData(file::ReadAll(path, NULL)); SquareTree sqt(prefsData); const char *langCode = sqt.root ? sqt.root->GetValue("UiLanguage") : NULL; if (langCode) { plogf("sp: UiLanguage from preferences: %s", langCode); for (int i = 0; gLanguages[i]; i++) { if (str::Eq(gLanguages[i], langCode)) { gTranslationIdx = i * gTranslationsCount; break; } } } }
void Localization::SetLanguage(const QString& language) { if (language.isEmpty()) { URHO3D_LOGWARNING("Localization::SetLanguage(language): language name is empty"); return; } if (GetNumLanguages() == 0) { URHO3D_LOGWARNING("Localization::SetLanguage(language): no loaded languages"); return; } int index = GetLanguageIndex(language); if (index == -1) { URHO3D_LOGWARNING("Localization::SetLanguage(language): language not found"); return; } SetLanguage(index); }
bool CCaptionParser::ParseManagementData(const BYTE *pData, const DWORD DataSize) { if (DataSize < 2 + 5 + 3) return false; DWORD Pos = 0; const BYTE TMD = pData[Pos++] >> 6; if (TMD == 0x02) { // OTM Pos += 5; } const BYTE NumLanguages = pData[Pos++]; if (Pos + NumLanguages * 5 + 3 > DataSize) return false; bool fChanged = false; for (BYTE i = 0; i < NumLanguages; i++) { LanguageInfo LangInfo; LangInfo.LanguageTag = pData[Pos] >> 5; LangInfo.DMF = pData[Pos] & 0x0F; if (LangInfo.DMF == 0x0C || LangInfo.DMF == 0x0D) { LangInfo.DC = pData[Pos + 1]; Pos++; } LangInfo.LanguageCode[0] = pData[Pos + 1]; LangInfo.LanguageCode[1] = pData[Pos + 2]; LangInfo.LanguageCode[2] = pData[Pos + 3]; LangInfo.LanguageCode[3] = '\0'; LangInfo.Format = pData[Pos + 4] >> 4; LangInfo.TCS = (pData[Pos + 4] & 0x0C) >> 2; LangInfo.RollupMode = pData[Pos + 4] & 0x03; int Index = GetLanguageIndex(LangInfo.LanguageTag); if (Index < 0) { m_LanguageList.push_back(LangInfo); fChanged = true; } else { if (m_LanguageList[Index] != LangInfo) { m_LanguageList[Index] = LangInfo; fChanged = true; } } Pos += 5; } if (fChanged && m_pHandler != NULL) m_pHandler->OnLanguageUpdate(this); const DWORD UnitLoopLength = ((DWORD)pData[Pos] << 16) | ((DWORD)pData[Pos + 1] << 8) | (DWORD)pData[Pos + 2]; Pos += 3; if (UnitLoopLength > 0 && Pos + UnitLoopLength <= DataSize) { DWORD ReadSize = 0; do { DWORD Size = UnitLoopLength - ReadSize; if (!ParseUnitData(&pData[Pos + ReadSize], &Size)) return false; ReadSize += Size; } while (ReadSize < UnitLoopLength); } return true; }
/** * Load a TEXT data block into the object. * @param rcd_file Input file. * @return Load was successful. */ bool TextData::Load(RcdFileReader *rcd_file) { uint8 buffer[64*1024]; // Arbitrary sized block of temporary memory to store the text data. size_t used_size = 0; uint32 length = rcd_file->size; if (rcd_file->version != 2) return false; TextString strings[MAX_NUM_TEXT_STRINGS]; uint used_strings = 0; while (length > 0) { if (used_strings >= lengthof(strings)) return false; // Too many text strings. if (length < 3) return false; int str_length = rcd_file->GetUInt16(); int ident_length = rcd_file->GetUInt8(); if (static_cast<uint32>(str_length) > length) return false; // String does not fit in the block. length -= 3; if (ident_length + 2 + 1 >= str_length) return false; // No space for translations. int trs_length = str_length - (ident_length + 2 + 1); /* Read string name. */ strings[used_strings].name = (char *)buffer + used_size; if (!ReadUtf8Text(rcd_file, ident_length, buffer, lengthof(buffer), &used_size)) return false; length -= ident_length; while (trs_length > 0) { if (length < 3) return false; int tr_length = rcd_file->GetUInt16(); int lang_length = rcd_file->GetUInt8(); length -= 3; if (tr_length > trs_length) return false; if (lang_length + 2 + 1 >= tr_length) return false; int text_length = tr_length - (lang_length + 2 + 1); uint8 lang_buffer[1000]; // Arbitrary sized block to store the language name or a single string. size_t used = 0; /* Read translation language string. */ if (!ReadUtf8Text(rcd_file, lang_length, lang_buffer, lengthof(lang_buffer), &used)) return false; length -= lang_length; int lang_idx = GetLanguageIndex((char *)lang_buffer); /* Read translation text. */ if (lang_idx >= 0) { strings[used_strings].languages[lang_idx] = buffer + used_size; if (!ReadUtf8Text(rcd_file, text_length, buffer, lengthof(buffer), &used_size)) return false; } else { /* Illegal language, read into a dummy buffer. */ used = 0; if (!ReadUtf8Text(rcd_file, text_length, lang_buffer, lengthof(lang_buffer), &used)) return false; } length -= text_length; trs_length -= 3 + lang_length + text_length; } assert(trs_length == 0); used_strings++; } assert (length == 0); this->strings = new TextString[used_strings]; this->string_count = used_strings; this->text_data = new uint8[used_size]; if (this->strings == nullptr || this->text_data == nullptr) return false; memcpy(this->text_data, buffer, used_size); for (uint i = 0; i < used_strings; i++) { this->strings[i].name = (strings[i].name == nullptr) ? nullptr : (char *)this->text_data + ((uint8 *)(strings[i].name) - buffer); for (uint lng = 0; lng < LANGUAGE_COUNT; lng++) { this->strings[i].languages[lng] = (strings[i].languages[lng] == nullptr) ? nullptr : this->text_data + (strings[i].languages[lng] - buffer); } } return true; }
void SelectTranslation(const WCHAR *exePath=NULL) { LANGID langId = GetUserDefaultUILanguage(); int idx = GetLanguageIndex(langId); if (-1 == idx) { // try a neutral language if the specific sublanguage isn't available langId = MAKELANGID(PRIMARYLANGID(langId), SUBLANG_NEUTRAL); idx = GetLanguageIndex(langId); } if (-1 != idx) { gTranslationIdx = idx; plogf("sp: Detected language %s (%d)", gLanguages[idx / gTranslationsCount], idx); } // try to extract the language used by SumatraPDF ScopedMem<WCHAR> path; if (exePath) { path.Set(path::GetDir(exePath)); path.Set(path::Join(path, PREFS_FILE_NAME)); } if (!file::Exists(path)) { path.Set(GetSpecialFolder(CSIDL_APPDATA)); path.Set(path::Join(path, L"SumatraPDF\\" PREFS_FILE_NAME)); } if (!file::Exists(path)) return; plogf("sp: Found preferences at %S", path); #ifndef USE_INI_SETTINGS ScopedMem<char> data(file::ReadAll(path, NULL)); if (data) { BencObj *root = BencObj::Decode(data); if (root && root->Type() == BT_DICT) { BencDict *global = static_cast<BencDict *>(root)->GetDict("gp"); BencString *string = global ? global->GetString("UILanguage") : NULL; if (string) { plogf("sp: UILanguage from preferences: %s", string->RawValue()); for (int i = 0; gLanguages[i]; i++) { if (str::Eq(gLanguages[i], string->RawValue())) { gTranslationIdx = i * gTranslationsCount; break; } } } } delete root; } #else IniFile ini(path); IniSection *section = ini.FindSection(NULL); IniLine *line = section ? section->FindLine("CurrLangCode") : NULL; if (line) { plogf("sp: UILanguage from preferences: %s", line->value); for (int i = 0; gLanguages[i]; i++) { if (str::Eq(gLanguages[i], line->value)) { gTranslationIdx = i * gTranslationsCount; break; } } } #endif }