// This method takes an attributed string and outputs a GlyphLayout data // structure that contains the glyph number and location of each inidividual glyph void getGlyphLayout (const AttributedString& text, GlyphLayout& glyphLayout) { // For now we are creating the DirectWrite Factory, System Font Collection, // D2D Factory and GDI Render target every time we layout text. // This is inefficient and we may be loading and unloading libraries each layout. // These four things should be created once at application startup and be destroyed // when the application exits. I'm not sure where the best place to do this so // for now I will just use the inefficient method. IDWriteFactory* dwFactory = nullptr; HRESULT hr = DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(&dwFactory)); IDWriteFontCollection* dwFontCollection = nullptr; hr = dwFactory->GetSystemFontCollection (&dwFontCollection); // To add color to text, we need to create a D2D render target // Since we are not actually rendering to a D2D context we create a temporary GDI render target ID2D1Factory *d2dFactory = nullptr; hr = D2D1CreateFactory (D2D1_FACTORY_TYPE_SINGLE_THREADED, &d2dFactory); D2D1_RENDER_TARGET_PROPERTIES d2dRTProp = D2D1::RenderTargetProperties( D2D1_RENDER_TARGET_TYPE_SOFTWARE, D2D1::PixelFormat( DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE), 0, 0, D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE, D2D1_FEATURE_LEVEL_DEFAULT ); ID2D1DCRenderTarget* d2dDCRT = nullptr; hr = d2dFactory->CreateDCRenderTarget (&d2dRTProp, &d2dDCRT); // Initially we set the paragraph up with a default font and then apply the attributed string ranges later Font defaultFont; const float defaultFontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (defaultFont, *dwFontCollection); // We should probably be detecting the locale instead of hard coding it to en-us String localeName("en-us"); // We multiply the font height by the size factor so we layout text at the correct size IDWriteTextFormat* dwTextFormat = nullptr; hr = dwFactory->CreateTextFormat ( defaultFont.getTypefaceName().toWideCharPointer(), dwFontCollection, DWRITE_FONT_WEIGHT_REGULAR, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, defaultFont.getHeight() * defaultFontHeightToEmSizeFactor, localeName.toWideCharPointer(), &dwTextFormat ); // Paragraph Attributes // Set Paragraph Alignment if (text.getTextAlignment() == AttributedString::left) dwTextFormat->SetTextAlignment (DWRITE_TEXT_ALIGNMENT_LEADING); if (text.getTextAlignment() == AttributedString::right) dwTextFormat->SetTextAlignment (DWRITE_TEXT_ALIGNMENT_TRAILING); if (text.getTextAlignment() == AttributedString::center) dwTextFormat->SetTextAlignment (DWRITE_TEXT_ALIGNMENT_CENTER); // DirectWrite cannot justify text, default to left alignment if (text.getTextAlignment() == AttributedString::justified) dwTextFormat->SetTextAlignment (DWRITE_TEXT_ALIGNMENT_LEADING); // Set Word Wrap if (text.getWordWrap() == AttributedString::none) dwTextFormat->SetWordWrapping (DWRITE_WORD_WRAPPING_NO_WRAP); if (text.getWordWrap() == AttributedString::byWord) dwTextFormat->SetWordWrapping (DWRITE_WORD_WRAPPING_WRAP); // DirectWrite does not support wrapping by character, default to wrapping by word if (text.getWordWrap() == AttributedString::byChar) dwTextFormat->SetWordWrapping (DWRITE_WORD_WRAPPING_WRAP); // DirectWrite does not automatically set reading direction // This must be set correctly and manually when using RTL Scripts (Hebrew, Arabic) if (text.getReadingDirection() == AttributedString::rightToLeft) dwTextFormat->SetReadingDirection (DWRITE_READING_DIRECTION_RIGHT_TO_LEFT); IDWriteTextLayout* dwTextLayout = nullptr; hr = dwFactory->CreateTextLayout ( text.getText().toWideCharPointer(), text.getText().length(), dwTextFormat, glyphLayout.getWidth(), glyphLayout.getHeight(), &dwTextLayout ); // Character Attributes int numCharacterAttributes = text.getCharAttributesSize(); for (int i = 0; i < numCharacterAttributes; ++i) { Attr* attr = text.getCharAttribute (i); // Character Range Error Checking if (attr->range.getStart() > text.getText().length()) continue; if (attr->range.getEnd() > text.getText().length()) attr->range.setEnd (text.getText().length()); if (attr->attribute == Attr::font) { AttrFont* attrFont = static_cast<AttrFont*>(attr); DWRITE_TEXT_RANGE dwRange; dwRange.startPosition = attrFont->range.getStart(); dwRange.length = attrFont->range.getLength(); dwTextLayout->SetFontFamilyName (attrFont->font.getTypefaceName().toWideCharPointer(), dwRange); // We multiply the font height by the size factor so we layout text at the correct size const float fontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (attrFont->font, *dwFontCollection); dwTextLayout->SetFontSize (attrFont->font.getHeight() * fontHeightToEmSizeFactor, dwRange); } if (attr->attribute == Attr::foregroundColour) { AttrColour* attrColour = static_cast<AttrColour*>(attr); DWRITE_TEXT_RANGE dwRange; dwRange.startPosition = attrColour->range.getStart(); dwRange.length = attrColour->range.getLength(); ID2D1SolidColorBrush* d2dBrush = nullptr; d2dDCRT->CreateSolidColorBrush (D2D1::ColorF (D2D1::ColorF(attrColour->colour.getFloatRed(), attrColour->colour.getFloatGreen(), attrColour->colour.getFloatBlue(), attrColour->colour.getFloatAlpha())), &d2dBrush); // We need to call SetDrawingEffect with a legimate brush to get DirectWrite to break text based on colours dwTextLayout->SetDrawingEffect (d2dBrush, dwRange); safeRelease (&d2dBrush); } } UINT32 actualLineCount = 0; hr = dwTextLayout->GetLineMetrics (nullptr, 0, &actualLineCount); // Preallocate GlyphLayout Line Array glyphLayout.setNumLines (actualLineCount); HeapBlock <DWRITE_LINE_METRICS> dwLineMetrics (actualLineCount); hr = dwTextLayout->GetLineMetrics (dwLineMetrics, actualLineCount, &actualLineCount); int location = 0; // Create GlyphLine structures for each line in the layout for (UINT32 i = 0; i < actualLineCount; ++i) { // Get string range Range<int> lineStringRange (location, (int) location + dwLineMetrics[i].length); location = dwLineMetrics[i].length; GlyphLine* glyphLine = new GlyphLine(); glyphLine->setStringRange (lineStringRange); glyphLayout.addGlyphLine (glyphLine); } // To copy glyph data from DirectWrite into our own data structures we must create our // own CustomTextRenderer. Instead of passing the draw method an actual graphics context, // we pass it the GlyphLayout object that needs to be filled with glyphs. CustomDirectWriteTextRenderer* textRenderer = nullptr; textRenderer = new CustomDirectWriteTextRenderer(); hr = dwTextLayout->Draw ( &glyphLayout, textRenderer, glyphLayout.getX(), glyphLayout.getY() ); safeRelease (&textRenderer); safeRelease (&dwTextLayout); safeRelease (&dwTextFormat); safeRelease (&d2dDCRT); safeRelease (&d2dFactory); safeRelease (&dwFontCollection); safeRelease (&dwFactory); }
static jstring getCurrencyName(JNIEnv* env, jstring javaLocaleName, jstring javaCurrencyCode, UCurrNameStyle nameStyle) { ScopedUtfChars localeName(env, javaLocaleName); if (localeName.c_str() == NULL) { return NULL; } ScopedJavaUnicodeString currencyCode(env, javaCurrencyCode); if (!currencyCode.valid()) { return NULL; } UnicodeString icuCurrencyCode(currencyCode.unicodeString()); UErrorCode status = U_ZERO_ERROR; UBool isChoiceFormat = false; int32_t charCount; const UChar* chars = ucurr_getName(icuCurrencyCode.getTerminatedBuffer(), localeName.c_str(), nameStyle, &isChoiceFormat, &charCount, &status); if (status == U_USING_DEFAULT_WARNING) { if (nameStyle == UCURR_SYMBOL_NAME) { // ICU doesn't distinguish between falling back to the root locale and meeting a genuinely // unknown currency. The Currency class does. if (!ucurr_isAvailable(icuCurrencyCode.getTerminatedBuffer(), U_DATE_MIN, U_DATE_MAX, &status)) { return NULL; } } if (nameStyle == UCURR_LONG_NAME) { // ICU's default is English. We want the ISO 4217 currency code instead. chars = icuCurrencyCode.getBuffer(); charCount = icuCurrencyCode.length(); } } return (charCount == 0) ? NULL : env->NewString(chars, charCount); }
UnicodeString RuleBasedNumberFormat::getRuleSetDisplayName(int32_t index, const Locale& localeParam) { if (localizations && index >= 0 && index < localizations->getNumberOfRuleSets()) { UnicodeString localeName(localeParam.getBaseName(), -1, UnicodeString::kInvariant); int32_t len = localeName.length(); UChar* localeStr = localeName.getBuffer(len + 1); while (len >= 0) { localeStr[len] = 0; int32_t ix = localizations->indexForLocale(localeStr); if (ix >= 0) { UnicodeString name(TRUE, localizations->getDisplayName(ix, index), -1); return name; } // trim trailing portion, skipping over ommitted sections do { --len;} while (len > 0 && localeStr[len] != 0x005f); // underscore while (len > 0 && localeStr[len-1] == 0x005F) --len; } UnicodeString name(TRUE, localizations->getRuleSetName(index), -1); return name; } UnicodeString bogus; bogus.setToBogus(); return bogus; }
static jstring ICU_getCurrencySymbol(JNIEnv* env, jclass, jstring locale, jstring currencyCode) { // We can't use ucurr_getName because it doesn't distinguish between using data root from // the root locale and parroting back the input because it's never heard of the currency code. ScopedUtfChars localeName(env, locale); UErrorCode status = U_ZERO_ERROR; ScopedResourceBundle currLoc(ures_open(U_ICUDATA_CURR, localeName.c_str(), &status)); if (U_FAILURE(status)) { return NULL; } ScopedResourceBundle currencies(ures_getByKey(currLoc.get(), "Currencies", NULL, &status)); if (U_FAILURE(status)) { return NULL; } ScopedUtfChars currency(env, currencyCode); ScopedResourceBundle currencyElems(ures_getByKey(currencies.get(), currency.c_str(), NULL, &status)); if (U_FAILURE(status)) { return NULL; } int32_t charCount; const jchar* chars = ures_getStringByIndex(currencyElems.get(), 0, &charCount, &status); if (U_FAILURE(status)) { return NULL; } return (charCount == 0) ? NULL : env->NewString(chars, charCount); }
static jstring ICU_getCurrencySymbolNative(JNIEnv* env, jclass, jstring locale, jstring currencyCode) { ScopedUtfChars localeName(env, locale); UErrorCode status = U_ZERO_ERROR; ScopedResourceBundle currLoc(ures_open(U_ICUDATA_CURR, localeName.c_str(), &status)); if (U_FAILURE(status)) { return NULL; } ScopedResourceBundle currencies(ures_getByKey(currLoc.get(), "Currencies", NULL, &status)); if (U_FAILURE(status)) { return NULL; } ScopedUtfChars currency(env, currencyCode); ScopedResourceBundle currencyElems(ures_getByKey(currencies.get(), currency.c_str(), NULL, &status)); if (U_FAILURE(status)) { return NULL; } int currSymbL; const jchar* currSymbU = ures_getStringByIndex(currencyElems.get(), 0, &currSymbL, &status); if (U_FAILURE(status)) { return NULL; } return (currSymbL == 0) ? NULL : env->NewString(currSymbU, currSymbL); }
int main(int argc, char *argv[]) { Kst::Application app(argc, argv); //-------- QTranslator qtTranslator; qtTranslator.load(QLatin1String("qt_") + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); app.installTranslator(&qtTranslator); QLatin1String localeSuffix("/locale"); QString localeName(QLatin1String("kst_common_") + QLocale::system().name()); // The "installed to system" localization: // FIXME: see https://bugs.kde.org/show_bug.cgi?id=323197 #ifdef PKGDATADIR QTranslator appSystemTranslator; appSystemTranslator.load(localeName, PKGDATADIR + localeSuffix); app.installTranslator(&appSystemTranslator); #endif // The "in the directory with the binary" localization QTranslator kstDirectoryTranslator; kstDirectoryTranslator.load(localeName, app.applicationDirPath() + localeSuffix); app.installTranslator(&kstDirectoryTranslator); if (app.mainWindow()->initFromCommandLine()) { app.mainWindow()->show(); return app.exec(); } return 0; }
std::locale getCurrentStdLocale() { std::locale loc; try { // use the system locale provided by Qt #ifdef WIN32 // need to change locale given by Qt from underscore to hyphenated ("sv_SE" to "sv-SE") // although std::locale should only accept locales with underscore, e.g. "sv_SE" std::string localeName(QLocale::system().name().replace('_', '-').toStdString()); #else std::string localeName(QLocale::system().name().toStdString()); #endif loc = std::locale(localeName.c_str()); } catch (std::exception &e) { LogWarnCustom("getStdLocale", "Locale could not be set. " << e.what()); } return loc; }
static jstring ICU_getCurrencyDisplayName(JNIEnv* env, jclass, jstring javaLocaleName, jstring javaCurrencyCode) { ScopedUtfChars localeName(env, javaLocaleName); ScopedJavaUnicodeString currencyCode(env, javaCurrencyCode); UnicodeString icuCurrencyCode(currencyCode.unicodeString()); UErrorCode status = U_ZERO_ERROR; UBool isChoiceFormat; int32_t charCount; const UChar* chars = ucurr_getName(icuCurrencyCode.getTerminatedBuffer(), localeName.c_str(), UCURR_LONG_NAME, &isChoiceFormat, &charCount, &status); if (status == U_USING_DEFAULT_WARNING) { // ICU's default is English. We want the ISO 4217 currency code instead. chars = icuCurrencyCode.getBuffer(); charCount = icuCurrencyCode.length(); } return (charCount == 0) ? NULL : env->NewString(chars, charCount); }
static jlong NativePluralRules_forLocaleImpl(JNIEnv* env, jclass, jstring javaLocaleName) { // The icu4c PluralRules returns a "other: n" default rule for the deprecated locales Java uses. // Work around this by translating back to the current language codes. std::string localeName(ScopedUtfChars(env, javaLocaleName).c_str()); if (localeName[0] == 'i' && localeName[1] == 'w') { localeName[0] = 'h'; localeName[1] = 'e'; } else if (localeName[0] == 'i' && localeName[1] == 'n') { localeName[0] = 'i'; localeName[1] = 'd'; } else if (localeName[0] == 'j' && localeName[1] == 'i') { localeName[0] = 'y'; localeName[1] = 'i'; } icu::Locale locale = icu::Locale::createFromName(localeName.c_str()); UErrorCode status = U_ZERO_ERROR; icu::PluralRules* result = icu::PluralRules::forLocale(locale, status); maybeThrowIcuException(env, "PluralRules::forLocale", status); return reinterpret_cast<uintptr_t>(result); }
NS_IMETHODIMP nsScriptableDateFormat::FormatDateTime( const char16_t *aLocale, nsDateFormatSelector dateFormatSelector, nsTimeFormatSelector timeFormatSelector, int32_t year, int32_t month, int32_t day, int32_t hour, int32_t minute, int32_t second, char16_t **dateTimeString) { // We can't have a valid date with the year, month or day // being lower than 1. if (year < 1 || month < 1 || day < 1) return NS_ERROR_INVALID_ARG; nsresult rv; nsAutoString localeName(aLocale); *dateTimeString = nullptr; nsCOMPtr<nsILocale> locale; // re-initialise locale pointer only if the locale was given explicitly if (!localeName.IsEmpty()) { // get locale service nsCOMPtr<nsILocaleService> localeService(do_GetService(kLocaleServiceCID, &rv)); NS_ENSURE_SUCCESS(rv, rv); // get locale rv = localeService->NewLocale(localeName, getter_AddRefs(locale)); NS_ENSURE_SUCCESS(rv, rv); } nsCOMPtr<nsIDateTimeFormat> dateTimeFormat(do_CreateInstance(kDateTimeFormatCID, &rv)); NS_ENSURE_SUCCESS(rv, rv); tm tmTime; time_t timetTime; memset(&tmTime, 0, sizeof(tmTime)); tmTime.tm_year = year - 1900; tmTime.tm_mon = month - 1; tmTime.tm_mday = day; tmTime.tm_hour = hour; tmTime.tm_min = minute; tmTime.tm_sec = second; tmTime.tm_yday = tmTime.tm_wday = 0; tmTime.tm_isdst = -1; timetTime = mktime(&tmTime); if ((time_t)-1 != timetTime) { rv = dateTimeFormat->FormatTime(locale, dateFormatSelector, timeFormatSelector, timetTime, mStringOut); } else { // if mktime fails (e.g. year <= 1970), then try NSPR. PRTime prtime; char string[32]; sprintf(string, "%.2d/%.2d/%d %.2d:%.2d:%.2d", month, day, year, hour, minute, second); if (PR_SUCCESS != PR_ParseTimeString(string, false, &prtime)) return NS_ERROR_INVALID_ARG; rv = dateTimeFormat->FormatPRTime(locale, dateFormatSelector, timeFormatSelector, prtime, mStringOut); } if (NS_SUCCEEDED(rv)) *dateTimeString = ToNewUnicode(mStringOut); return rv; }
extern "C" jboolean Java_libcore_icu_ICU_initLocaleDataNative(JNIEnv* env, jclass, jstring javaLocaleName, jobject localeData) { ScopedUtfChars localeName(env, javaLocaleName); if (localeName.c_str() == NULL) { return JNI_FALSE; } if (localeName.size() >= ULOC_FULLNAME_CAPACITY) { return JNI_FALSE; // ICU has a fixed-length limit. } // Get the DateTimePatterns. UErrorCode status = U_ZERO_ERROR; bool foundDateTimePatterns = false; for (LocaleNameIterator it(localeName.c_str(), status); it.HasNext(); it.Up()) { if (getDateTimePatterns(env, localeData, it.Get())) { foundDateTimePatterns = true; break; } } if (!foundDateTimePatterns) { ALOGE("Couldn't find ICU DateTimePatterns for %s", localeName.c_str()); return JNI_FALSE; } // Get the "Yesterday", "Today", and "Tomorrow" strings. bool foundYesterdayTodayAndTomorrow = false; for (LocaleNameIterator it(localeName.c_str(), status); it.HasNext(); it.Up()) { if (getYesterdayTodayAndTomorrow(env, localeData, it.Get())) { foundYesterdayTodayAndTomorrow = true; break; } } if (!foundYesterdayTodayAndTomorrow) { ALOGE("Couldn't find ICU yesterday/today/tomorrow for %s", localeName.c_str()); return JNI_FALSE; } status = U_ZERO_ERROR; Locale locale = getLocale(env, javaLocaleName); UniquePtr<Calendar> cal(Calendar::createInstance(locale, status)); if (U_FAILURE(status)) { return JNI_FALSE; } setIntegerField(env, localeData, "firstDayOfWeek", cal->getFirstDayOfWeek()); setIntegerField(env, localeData, "minimalDaysInFirstWeek", cal->getMinimalDaysInFirstWeek()); // Get DateFormatSymbols. status = U_ZERO_ERROR; DateFormatSymbols dateFormatSym(locale, status); if (U_FAILURE(status)) { return JNI_FALSE; } // Get AM/PM and BC/AD. int32_t count = 0; const UnicodeString* amPmStrs = dateFormatSym.getAmPmStrings(count); setStringArrayField(env, localeData, "amPm", amPmStrs, count); const UnicodeString* erasStrs = dateFormatSym.getEras(count); setStringArrayField(env, localeData, "eras", erasStrs, count); const UnicodeString* longMonthNames = dateFormatSym.getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); setStringArrayField(env, localeData, "longMonthNames", longMonthNames, count); const UnicodeString* shortMonthNames = dateFormatSym.getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); setStringArrayField(env, localeData, "shortMonthNames", shortMonthNames, count); const UnicodeString* tinyMonthNames = dateFormatSym.getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); setStringArrayField(env, localeData, "tinyMonthNames", tinyMonthNames, count); const UnicodeString* longWeekdayNames = dateFormatSym.getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); setStringArrayField(env, localeData, "longWeekdayNames", longWeekdayNames, count); const UnicodeString* shortWeekdayNames = dateFormatSym.getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); setStringArrayField(env, localeData, "shortWeekdayNames", shortWeekdayNames, count); const UnicodeString* tinyWeekdayNames = dateFormatSym.getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); setStringArrayField(env, localeData, "tinyWeekdayNames", tinyWeekdayNames, count); const UnicodeString* longStandAloneMonthNames = dateFormatSym.getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); setStringArrayField(env, localeData, "longStandAloneMonthNames", longStandAloneMonthNames, count); const UnicodeString* shortStandAloneMonthNames = dateFormatSym.getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); setStringArrayField(env, localeData, "shortStandAloneMonthNames", shortStandAloneMonthNames, count); const UnicodeString* tinyStandAloneMonthNames = dateFormatSym.getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); setStringArrayField(env, localeData, "tinyStandAloneMonthNames", tinyStandAloneMonthNames, count); const UnicodeString* longStandAloneWeekdayNames = dateFormatSym.getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); setStringArrayField(env, localeData, "longStandAloneWeekdayNames", longStandAloneWeekdayNames, count); const UnicodeString* shortStandAloneWeekdayNames = dateFormatSym.getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); setStringArrayField(env, localeData, "shortStandAloneWeekdayNames", shortStandAloneWeekdayNames, count); const UnicodeString* tinyStandAloneWeekdayNames = dateFormatSym.getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); setStringArrayField(env, localeData, "tinyStandAloneWeekdayNames", tinyStandAloneWeekdayNames, count); status = U_ZERO_ERROR; // For numberPatterns and symbols. setNumberPatterns(env, localeData, locale); setDecimalFormatSymbolsData(env, localeData, locale); jstring countryCode = env->NewStringUTF(Locale::createFromName(localeName.c_str()).getCountry()); jstring internationalCurrencySymbol = Java_libcore_icu_ICU_getCurrencyCode(env, NULL, countryCode); env->DeleteLocalRef(countryCode); countryCode = NULL; jstring currencySymbol = NULL; if (internationalCurrencySymbol != NULL) { currencySymbol = Java_libcore_icu_ICU_getCurrencySymbol(env, NULL, javaLocaleName, internationalCurrencySymbol); } else { internationalCurrencySymbol = env->NewStringUTF("XXX"); } if (currencySymbol == NULL) { // This is the UTF-8 encoding of U+00A4 (CURRENCY SIGN). currencySymbol = env->NewStringUTF("\xc2\xa4"); } setStringField(env, localeData, "currencySymbol", currencySymbol); setStringField(env, localeData, "internationalCurrencySymbol", internationalCurrencySymbol); return JNI_TRUE; }
static jboolean ICU_initLocaleDataImpl(JNIEnv* env, jclass, jstring locale, jobject localeData) { ScopedUtfChars localeName(env, locale); if (localeName.c_str() == NULL) { return JNI_FALSE; } // Get DateTimePatterns UErrorCode status; char currentLocale[ULOC_FULLNAME_CAPACITY]; int32_t localeNameLen = 0; if (localeName.size() >= ULOC_FULLNAME_CAPACITY) { return JNI_FALSE; // Exceed ICU defined limit of the whole locale ID. } strcpy(currentLocale, localeName.c_str()); do { status = U_ZERO_ERROR; ScopedResourceBundle root(ures_open(NULL, currentLocale, &status)); if (U_FAILURE(status)) { if (localeNameLen == 0) { break; // No parent locale, report this error outside the loop. } else { status = U_ZERO_ERROR; continue; // get parent locale. } } ScopedResourceBundle calendar(ures_getByKey(root.get(), "calendar", NULL, &status)); if (U_FAILURE(status)) { status = U_ZERO_ERROR; continue; // get parent locale. } ScopedResourceBundle gregorian(ures_getByKey(calendar.get(), "gregorian", NULL, &status)); if (U_FAILURE(status)) { status = U_ZERO_ERROR; continue; // get parent locale. } ScopedResourceBundle dateTimePatterns(ures_getByKey(gregorian.get(), "DateTimePatterns", NULL, &status)); if (U_SUCCESS(status)) { setStringField(env, localeData, "fullTimeFormat", dateTimePatterns.get(), 0); setStringField(env, localeData, "longTimeFormat", dateTimePatterns.get(), 1); setStringField(env, localeData, "mediumTimeFormat", dateTimePatterns.get(), 2); setStringField(env, localeData, "shortTimeFormat", dateTimePatterns.get(), 3); setStringField(env, localeData, "fullDateFormat", dateTimePatterns.get(), 4); setStringField(env, localeData, "longDateFormat", dateTimePatterns.get(), 5); setStringField(env, localeData, "mediumDateFormat", dateTimePatterns.get(), 6); setStringField(env, localeData, "shortDateFormat", dateTimePatterns.get(), 7); break; } else { status = U_ZERO_ERROR; // get parent locale. } } while((localeNameLen = uloc_getParent(currentLocale, currentLocale, sizeof(currentLocale), &status)) >= 0); if (U_FAILURE(status)) { ALOGE("Error getting ICU resource bundle: %s", u_errorName(status)); return JNI_FALSE; } status = U_ZERO_ERROR; Locale localeObj = getLocale(env, locale); UniquePtr<Calendar> cal(Calendar::createInstance(localeObj, status)); if (U_FAILURE(status)) { return JNI_FALSE; } setIntegerField(env, localeData, "firstDayOfWeek", cal->getFirstDayOfWeek()); setIntegerField(env, localeData, "minimalDaysInFirstWeek", cal->getMinimalDaysInFirstWeek()); // Get DateFormatSymbols status = U_ZERO_ERROR; DateFormatSymbols dateFormatSym(localeObj, status); if (U_FAILURE(status)) { return JNI_FALSE; } int32_t count = 0; // Get AM/PM marker const UnicodeString* amPmStrs = dateFormatSym.getAmPmStrings(count); setStringArrayField(env, localeData, "amPm", amPmStrs, count); const UnicodeString* erasStrs = dateFormatSym.getEras(count); setStringArrayField(env, localeData, "eras", erasStrs, count); const UnicodeString* longMonthNames = dateFormatSym.getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); setStringArrayField(env, localeData, "longMonthNames", longMonthNames, count); const UnicodeString* shortMonthNames = dateFormatSym.getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); setStringArrayField(env, localeData, "shortMonthNames", shortMonthNames, count); const UnicodeString* longWeekdayNames = dateFormatSym.getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); setStringArrayField(env, localeData, "longWeekdayNames", longWeekdayNames, count); const UnicodeString* shortWeekdayNames = dateFormatSym.getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); setStringArrayField(env, localeData, "shortWeekdayNames", shortWeekdayNames, count); const UnicodeString* longStandAloneMonthNames = dateFormatSym.getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); setStringArrayField(env, localeData, "longStandAloneMonthNames", longStandAloneMonthNames, count); const UnicodeString* shortStandAloneMonthNames = dateFormatSym.getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); setStringArrayField(env, localeData, "shortStandAloneMonthNames", shortStandAloneMonthNames, count); const UnicodeString* longStandAloneWeekdayNames = dateFormatSym.getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); setStringArrayField(env, localeData, "longStandAloneWeekdayNames", longStandAloneWeekdayNames, count); const UnicodeString* shortStandAloneWeekdayNames = dateFormatSym.getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); setStringArrayField(env, localeData, "shortStandAloneWeekdayNames", shortStandAloneWeekdayNames, count); status = U_ZERO_ERROR; // For numberPatterns and symbols. setNumberPatterns(env, localeData, locale); setDecimalFormatSymbolsData(env, localeData, locale); jstring countryCode = env->NewStringUTF(Locale::createFromName(localeName.c_str()).getCountry()); jstring internationalCurrencySymbol = ICU_getCurrencyCode(env, NULL, countryCode); env->DeleteLocalRef(countryCode); countryCode = NULL; jstring currencySymbol = NULL; if (internationalCurrencySymbol != NULL) { currencySymbol = ICU_getCurrencySymbol(env, NULL, locale, internationalCurrencySymbol); } else { internationalCurrencySymbol = env->NewStringUTF("XXX"); } if (currencySymbol == NULL) { // This is the UTF-8 encoding of U+00A4 (CURRENCY SIGN). currencySymbol = env->NewStringUTF("\xc2\xa4"); } setStringField(env, localeData, "currencySymbol", currencySymbol); setStringField(env, localeData, "internationalCurrencySymbol", internationalCurrencySymbol); return JNI_TRUE; }
void factory_new_locale(void) { nsresult result; nsCOMPtr<nsILocaleFactory> localeFactory; nsCOMPtr<nsILocale> locale; nsString* *category, *value; int i; nsString** categoryList, **valueList; PRUnichar *lc_name_unichar; localeFactory = do_GetClassObject(kLocaleFactoryCID, &result); NS_ASSERTION(NS_SUCCEEDED(result),"nsLocaleTest: factory_create_interface failed"); // // test NewLocale // nsAutoString localeName(NS_LITERALSTRING("ja-JP")); result = localeFactory->NewLocale(localeName, getter_AddRefs(locale)); NS_ASSERTION(NS_SUCCEEDED(result),"nsLocaleTest: factory_new_interface failed"); NS_ASSERTION(locale!=NULL,"nsLocaleTest: factory_new_interface failed"); for(i=0;i<6;i++) { category = new nsString(localeCategoryList[i]); value = new nsString(); result = locale->GetCategory(category, &lc_name_unichar); NS_ASSERTION(NS_SUCCEEDED(result),"nsLocaleTest: factory_new_interface failed"); value->SetString(lc_name_unichar); delete category; delete value; } categoryList = new nsStringArray(6); valueList = new nsStringArray(6); for(i=0;i<6;i++) { categoryList.InsertStringAt(localeCategoryList[i], i); valueList[i] = InsertStringAt(NS_LITERAL_STRING("x-netscape"), i); } result = localeFactory->NewLocale(categoryList,valueList,6,&locale); NS_ASSERTION(NS_SUCCEEDED(result),"nsLocaleTest: factory_new_interface failed"); NS_ASSERTION(locale!=NULL,"nsLocaleTest: factory_new_interface failed"); for(i=0;i<6;i++) { value = new nsString(); result = locale->GetCategory(categoryList[i], &lc_name_unichar); NS_ASSERTION(NS_SUCCEEDED(result),"nsLocaleTest: factory_new_interface failed"); value->SetString(lc_name_unichar); delete value; } for(i=0;i<6;i++) { delete categoryList.RemoveStringAt(i); delete valueList.RemoveStringAt(i); } delete categoryList; delete valueList; }
QString K3ChessSettings::localeIniFilePath() const { return localeIniFilePathFromName(localeName()); }
static jboolean ICU_initLocaleDataImpl(JNIEnv* env, jclass, jstring locale, jobject localeData) { ScopedUtfChars localeName(env, locale); UErrorCode status = U_ZERO_ERROR; ScopedResourceBundle root(ures_open(NULL, localeName.c_str(), &status)); if (U_FAILURE(status)) { LOGE("Error getting ICU resource bundle: %s", u_errorName(status)); status = U_ZERO_ERROR; return JNI_FALSE; } ScopedResourceBundle calendar(ures_getByKey(root.get(), "calendar", NULL, &status)); if (U_FAILURE(status)) { LOGE("Error getting ICU calendar resource bundle: %s", u_errorName(status)); return JNI_FALSE; } ScopedResourceBundle gregorian(ures_getByKey(calendar.get(), "gregorian", NULL, &status)); if (U_FAILURE(status)) { LOGE("Error getting ICU gregorian resource bundle: %s", u_errorName(status)); return JNI_FALSE; } int firstDayVals[] = { 0, 0 }; if (getDayIntVector(env, gregorian.get(), firstDayVals)) { setIntegerField(env, localeData, "firstDayOfWeek", firstDayVals[0]); setIntegerField(env, localeData, "minimalDaysInFirstWeek", firstDayVals[1]); } setStringArrayField(env, localeData, "amPm", getAmPmMarkers(env, gregorian.get())); setStringArrayField(env, localeData, "eras", getEras(env, gregorian.get())); ScopedResourceBundle dayNames(ures_getByKey(gregorian.get(), "dayNames", NULL, &status)); ScopedResourceBundle monthNames(ures_getByKey(gregorian.get(), "monthNames", NULL, &status)); // Get the regular month and weekday names. jobjectArray longMonthNames = getNames(env, monthNames.get(), true, REGULAR, LONG); jobjectArray shortMonthNames = getNames(env, monthNames.get(), true, REGULAR, SHORT); jobjectArray longWeekdayNames = getNames(env, dayNames.get(), false, REGULAR, LONG); jobjectArray shortWeekdayNames = getNames(env, dayNames.get(), false, REGULAR, SHORT); setStringArrayField(env, localeData, "longMonthNames", longMonthNames); setStringArrayField(env, localeData, "shortMonthNames", shortMonthNames); setStringArrayField(env, localeData, "longWeekdayNames", longWeekdayNames); setStringArrayField(env, localeData, "shortWeekdayNames", shortWeekdayNames); // Get the stand-alone month and weekday names. If they're not available (as they aren't for // English), we reuse the regular names. If we returned null to Java, the usual fallback // mechanisms would come into play and we'd end up with the bogus stand-alone names from the // root locale ("1" for January, and so on). jobjectArray longStandAloneMonthNames = getNames(env, monthNames.get(), true, STAND_ALONE, LONG); if (longStandAloneMonthNames == NULL) { longStandAloneMonthNames = longMonthNames; } jobjectArray shortStandAloneMonthNames = getNames(env, monthNames.get(), true, STAND_ALONE, SHORT); if (shortStandAloneMonthNames == NULL) { shortStandAloneMonthNames = shortMonthNames; } jobjectArray longStandAloneWeekdayNames = getNames(env, dayNames.get(), false, STAND_ALONE, LONG); if (longStandAloneWeekdayNames == NULL) { longStandAloneWeekdayNames = longWeekdayNames; } jobjectArray shortStandAloneWeekdayNames = getNames(env, dayNames.get(), false, STAND_ALONE, SHORT); if (shortStandAloneWeekdayNames == NULL) { shortStandAloneWeekdayNames = shortWeekdayNames; } setStringArrayField(env, localeData, "longStandAloneMonthNames", longStandAloneMonthNames); setStringArrayField(env, localeData, "shortStandAloneMonthNames", shortStandAloneMonthNames); setStringArrayField(env, localeData, "longStandAloneWeekdayNames", longStandAloneWeekdayNames); setStringArrayField(env, localeData, "shortStandAloneWeekdayNames", shortStandAloneWeekdayNames); ScopedResourceBundle dateTimePatterns(ures_getByKey(gregorian.get(), "DateTimePatterns", NULL, &status)); if (U_SUCCESS(status)) { setStringField(env, localeData, "fullTimeFormat", dateTimePatterns.get(), 0); setStringField(env, localeData, "longTimeFormat", dateTimePatterns.get(), 1); setStringField(env, localeData, "mediumTimeFormat", dateTimePatterns.get(), 2); setStringField(env, localeData, "shortTimeFormat", dateTimePatterns.get(), 3); setStringField(env, localeData, "fullDateFormat", dateTimePatterns.get(), 4); setStringField(env, localeData, "longDateFormat", dateTimePatterns.get(), 5); setStringField(env, localeData, "mediumDateFormat", dateTimePatterns.get(), 6); setStringField(env, localeData, "shortDateFormat", dateTimePatterns.get(), 7); } status = U_ZERO_ERROR; ScopedResourceBundle numberElements(ures_getByKey(root.get(), "NumberElements", NULL, &status)); if (U_SUCCESS(status) && ures_getSize(numberElements.get()) >= 11) { setCharField(env, localeData, "zeroDigit", numberElements.get(), 4); setCharField(env, localeData, "digit", numberElements.get(), 5); setCharField(env, localeData, "decimalSeparator", numberElements.get(), 0); setCharField(env, localeData, "groupingSeparator", numberElements.get(), 1); setCharField(env, localeData, "patternSeparator", numberElements.get(), 2); setCharField(env, localeData, "percent", numberElements.get(), 3); setCharField(env, localeData, "perMill", numberElements.get(), 8); setCharField(env, localeData, "monetarySeparator", numberElements.get(), 0); setCharField(env, localeData, "minusSign", numberElements.get(), 6); setStringField(env, localeData, "exponentSeparator", numberElements.get(), 7); setStringField(env, localeData, "infinity", numberElements.get(), 9); setStringField(env, localeData, "NaN", numberElements.get(), 10); } status = U_ZERO_ERROR; jstring internationalCurrencySymbol = getIntCurrencyCode(env, locale); jstring currencySymbol = NULL; if (internationalCurrencySymbol != NULL) { currencySymbol = ICU_getCurrencySymbolNative(env, NULL, locale, internationalCurrencySymbol); } else { internationalCurrencySymbol = env->NewStringUTF("XXX"); } if (currencySymbol == NULL) { // This is the UTF-8 encoding of U+00A4 (CURRENCY SIGN). currencySymbol = env->NewStringUTF("\xc2\xa4"); } setStringField(env, localeData, "currencySymbol", currencySymbol); setStringField(env, localeData, "internationalCurrencySymbol", internationalCurrencySymbol); ScopedResourceBundle numberPatterns(ures_getByKey(root.get(), "NumberPatterns", NULL, &status)); if (U_SUCCESS(status) && ures_getSize(numberPatterns.get()) >= 3) { setStringField(env, localeData, "numberPattern", numberPatterns.get(), 0); setStringField(env, localeData, "currencyPattern", numberPatterns.get(), 1); setStringField(env, localeData, "percentPattern", numberPatterns.get(), 2); } return JNI_TRUE; }
int main(int argc, char **argv) { Common::registerMetaTypes(); QApplication app(argc, argv); Q_INIT_RESOURCE(icons); Q_INIT_RESOURCE(license); QTranslator qtTranslator; qtTranslator.load(QLatin1String("qt_") + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); app.installTranslator(&qtTranslator); QLatin1String localeSuffix("/locale"); QString localeName(QLatin1String("trojita_common_") + (qgetenv("KDE_LANG") == "x-test" ? QStringLiteral("x_test") : QLocale::system().name())); // The "installed to system" localization QTranslator appSystemTranslator; if (!Gui::Util::pkgDataDir().isEmpty()) { appSystemTranslator.load(localeName, Gui::Util::pkgDataDir() + localeSuffix); app.installTranslator(&appSystemTranslator); } // The "in the directory with the binary" localization QTranslator appDirectoryTranslator; appDirectoryTranslator.load(localeName, app.applicationDirPath() + localeSuffix); app.installTranslator(&appDirectoryTranslator); AppVersion::setGitVersion(); AppVersion::setCoreApplicationData(); app.setWindowIcon(UiUtils::loadIcon(QStringLiteral("trojita"))); QTextStream qOut(stdout, QIODevice::WriteOnly); QTextStream qErr(stderr, QIODevice::WriteOnly); const QStringList &arguments = app.arguments(); bool error = false; bool showHelp = false; bool showMainWindow = false; bool showComposeWindow = false; bool showAddressbookWindow = false; bool logToDisk = false; QString profileName; QString url; for (int i = 1; i < arguments.size(); ++i) { const QString &arg = arguments.at(i); if (arg.startsWith(QLatin1Char('-'))) { if (arg == QLatin1String("-m") || arg == QLatin1String("--mainwindow")) { showMainWindow = true; } else if (arg == QLatin1String("-a") || arg == QLatin1String("--addressbook")) { showAddressbookWindow = true; } else if (arg == QLatin1String("-c") || arg == QLatin1String("--compose")) { showComposeWindow = true; } else if (arg == QLatin1String("-h") || arg == QLatin1String("--help")) { showHelp = true; } else if (arg == QLatin1String("-p") || arg == QLatin1String("--profile")) { if (i+1 == arguments.size() || arguments.at(i+1).startsWith(QLatin1Char('-'))) { qErr << QObject::tr("Error: Profile was not specified") << endl; error = true; break; } else if (!profileName.isEmpty()) { qErr << QObject::tr("Error: Duplicate profile option '%1'").arg(arg) << endl; error = true; break; } else { profileName = arguments.at(i+1); ++i; } } else if (arg == QLatin1String("--log-to-disk")) { logToDisk = true; } else { qErr << QObject::tr("Warning: Unknown option '%1'").arg(arg) << endl; } } else { if (!url.isEmpty() || !arg.startsWith(QLatin1String("mailto:"))) { qErr << QObject::tr("Warning: Unexpected argument '%1'").arg(arg) << endl; } else { url = arg; showComposeWindow = true; } } } if (!showMainWindow && !showComposeWindow && !showAddressbookWindow) showMainWindow = true; if (error) showHelp = true; if (showHelp) { qOut << endl << QObject::trUtf8( "Usage: %1 [options] [url]\n" "\n" "Trojitá %2 - fast Qt IMAP e-mail client\n" "\n" "Options:\n" " -h, --help Show this help\n" " -m, --mainwindow Show main window (default when no option is provided)\n" " -a, --addressbook Show addressbook window\n" " -c, --compose Compose new email (default when url is provided)\n" " -p, --profile <profile> Set profile (cannot start with char '-')\n" " --log-to-disk Activate debug traffic logging to disk by default\n" "\n" "Arguments:\n" " url Mailto: url address for composing new email\n" ).arg(arguments.at(0), Common::Application::version) << endl; return error ? 1 : 0; } // Hack: support multiple "profiles" if (!profileName.isEmpty()) { // We are abusing the env vars here. Yes, it's a hidden global. Yes, it's ugly. // Take it or leave it, this is a time-limited hack. // The env var is also in UTF-8. I like UTF-8. qputenv("TROJITA_PROFILE", profileName.toUtf8()); } else { #ifndef Q_OS_WIN32 unsetenv("TROJITA_PROFILE"); #else putenv("TROJITA_PROFILE="); #endif } if (IPC::Instance::isRunning()) { if (showMainWindow) IPC::Instance::showMainWindow(); if (showAddressbookWindow) IPC::Instance::showAddressbookWindow(); if (showComposeWindow) IPC::Instance::composeMail(url); return 0; } QSettings settings(Common::Application::organization, profileName.isEmpty() ? Common::Application::name : Common::Application::name + QLatin1Char('-') + profileName); Gui::MainWindow win(&settings); QString errmsg; if (!IPC::registerInstance(&win, errmsg)) qErr << QObject::tr("Error: Registering IPC instance failed: %1").arg(errmsg) << endl; if ( settings.value(Common::SettingsNames::guiStartMinimized, QVariant(false)).toBool() ) { if ( !settings.value(Common::SettingsNames::guiShowSystray, QVariant(true)).toBool() ) { win.show(); win.setWindowState(Qt::WindowMinimized); } } else { win.show(); } if (showAddressbookWindow) win.invokeContactEditor(); if (showComposeWindow) { if (url.isEmpty()) win.slotComposeMail(); else win.slotComposeMailUrl(QUrl::fromEncoded(url.toUtf8())); } if (logToDisk) { win.enableLoggingToDisk(); } return app.exec(); }