Qt-contributors-summit-2013-Qt ICU: Difference between revisions
No edit summary |
m (Categorize) |
||
(5 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
{{Cleanup | reason=Auto-imported from ExpressionEngine.}} | |||
[[Category:QtCS2013]] | |||
'''<span class="caps">WIP</span>''' | '''<span class="caps">WIP</span>''' | ||
<div class="factbox right"> | |||
===Table of Content=== | |||
* [[#49098c06473b94079cd2cb087eea7952|Agenda]] | |||
* [[#f670ea66cfb0e90bd6090472ad692694|Minutes]] | |||
** [[#5f9c610aae0c0d7f272db36b320c0e66|ICU and Qt]] | |||
** [[#4f408028668c0280178deb641e8c8080|QTimeZone / QDateTime integration issues]] | |||
* [[#d6bbb58c95efc33091c923e295a4d9a5|Detailed notes on ICU in Qt5]] | |||
** [[#b9772d66f18ce56a276c4d3b25f408d5|Current use of ICU in Qt5]] | |||
** [[#7c6a6797f80131e4623bef193a12f0d8|Issues with ICU]] | |||
*** [[#d13bc5b68b2bd9e18f29777db17cc563|Common]] | |||
*** [[#aea23489ce3aa9b6406ebb28e0cda430|Windows]] | |||
*** [[#1748c0644a50090814d3e170723ccc5c|Mac]] | |||
*** [[#edc9f0a5a5d57797bf68e37364743831|Linux]] | |||
*** [[#e84e30b9390cdb64db6db2c9ab87846d|Android]] | |||
*** [[#dd95e601f6796907fc7efcbd086330f5|BB10 / QNX]] | |||
*** [[#24664ec765bdb273c6d4b82b194fccf5|QtWebKit]] | |||
** [[#b13e0cffea7586f134feda26d095766c|Possible solutions]] | |||
*** [[#369686331c93d55e587441143ccdf427|Localization]] | |||
*** [[#ac86a4f5479a464656ca11b4ca715d5a|Data size / build]] | |||
*** [[#24664ec765bdb273c6d4b82b194fccf5 0|QtWebKit]] | |||
** [[#d816f35dd7e9aa364b59b30dd3893fbf|ICU includes in QtWebKit]] | |||
** [[#2b9a0949d5be5c4facf5c205ada63ec7|ICU Documentation]] | |||
</div> | |||
=Agenda= | =Agenda= | ||
Line 10: | Line 39: | ||
Take by David Faure | Take by David Faure | ||
QSystemLocale picks up the user settings (bypassing <span class="caps">ICU</span>, which | QSystemLocale picks up the user settings (bypassing <span class="caps">ICU</span>, which doesn't do that).<br /> So it needs platform backends to do that. | ||
Same for the user-selected timezone, etc.<br /> = | Same for the user-selected timezone, etc.<br /> => <span class="caps">ICU</span> is really just the database. | ||
We need to complete that code, to get all settings on all OSes. | We need to complete that code, to get all settings on all OSes. | ||
Line 20: | Line 49: | ||
ICU4C lib = 5MB on top. | ICU4C lib = 5MB on top. | ||
Idea from Thiago: QLocale – basic, based on host apis Something more complete based on <span class="caps">ICU</span> - | Idea from Thiago: QLocale – basic, based on host apis Something more complete based on <span class="caps">ICU</span> -> in a separate module Could be done with QCollator, calendering and other future stuff, but not very consistent | ||
Idea from Lars: a stripped <span class="caps">ICU</span>. Translations would come from Qt po files. | Idea from Lars: a stripped <span class="caps">ICU</span>. Translations would come from Qt po files. | ||
Another option: load <span class="caps">ICU</span> dynamically, and use system apis if | Another option: load <span class="caps">ICU</span> dynamically, and use system apis if it's not available. | ||
Dropped idea: a plugin (loaded with native <span class="caps">API</span>s, no QString), which would also exist with<br /> minimal, small, and full versions. Creates a deployment problem. | Dropped idea: a plugin (loaded with native <span class="caps">API</span>s, no QString), which would also exist with<br /> minimal, small, and full versions. Creates a deployment problem. | ||
Line 30: | Line 59: | ||
Conclusions: | Conclusions: | ||
Mac: | Mac: we'll use the Mac <span class="caps">API</span> wrapper | ||
Android: <span class="caps">TODO</span>: check if we can use the <span class="caps">ICU</span> data files from ICU4J (same as the ones from ICU4C) <span class="caps">TODO</span>: check if we can use that data, even if the lib | Android: <span class="caps">TODO</span>: check if we can use the <span class="caps">ICU</span> data files from ICU4J (same as the ones from ICU4C) <span class="caps">TODO</span>: check if we can use that data, even if the lib isn't available. It should be the same version of <span class="caps">ICU</span> though! Or we could use <span class="caps">JNI</span>….. (everyone is horrified by the idea though). | ||
Idea from Lars: an <span class="caps">ICU</span>-compatible replacement <span class="caps">API</span>, that can be shipped instead of <span class="caps">ICU</span> to save size.<br /> QtCore uses 26 symbols from <span class="caps">ICU</span>.<br /> So the user could choose which <span class="caps">ICU</span> to use: 1) minimal (just C), 2) small (C and one selected locale?), 3) full.<br /> Whenever using QtWebKit, the full one is required. | Idea from Lars: an <span class="caps">ICU</span>-compatible replacement <span class="caps">API</span>, that can be shipped instead of <span class="caps">ICU</span> to save size.<br /> QtCore uses 26 symbols from <span class="caps">ICU</span>.<br /> So the user could choose which <span class="caps">ICU</span> to use: 1) minimal (just C), 2) small (C and one selected locale?), 3) full.<br /> Whenever using QtWebKit, the full one is required. It's really mutually exclusive (webkit uses 85 symbols from icu) | ||
==<span class="caps">ICU</span> and Qt== | ==<span class="caps">ICU</span> and Qt== | ||
Line 42: | Line 71: | ||
Primary issues: | Primary issues: | ||
* <span class="caps">ICU</span> ignores host data and any user custom settings, so may not appear | * <span class="caps">ICU</span> ignores host data and any user custom settings, so may not appear 'native' | ||
* BC issues with using system libraries limit us to using the C api which lacks features we may need | * BC issues with using system libraries limit us to using the C api which lacks features we may need | ||
* Mac | * Mac doesn't ship system library headers, App Store bans direct linking to libicu, out-dated system versions | ||
* Complaints from Windows devs that <span class="caps">ICU</span> download is too big to ship and has no debug version, but too hard to build / shrink the build themselves | * Complaints from Windows devs that <span class="caps">ICU</span> download is too big to ship and has no debug version, but too hard to build / shrink the build themselves | ||
* Android | * Android doesn't guarantee ICU4C will be installed(?), but offers no other <span class="caps">NDK</span> localization option(?) | ||
* Tizen also | * Tizen also doesn't ship <span class="caps">ICU</span> headers or allow linking to system <span class="caps">ICU</span> in its app store | ||
* QtWebKit has hard requirement that is not easily removed | * QtWebKit has hard requirement that is not easily removed | ||
Line 54: | Line 83: | ||
A default <span class="caps">ICU</span> 50.1 build with full data is 26.5 MB on disk or 10.5 MB zipped. Reduced to the minimum library and only the English locale, translation and mapping data the build is 10 MB on disk or 4.6 MB zipped. Further optimizations possible. An app choosing to ship <span class="caps">ICU</span> with a reasonable number of supported language translations can expect a build of about 12 MB on disk or 6 MB zipped. The big decision is whether this is an acceptable size for downloads on Win, Mac and Android. (see below). | A default <span class="caps">ICU</span> 50.1 build with full data is 26.5 MB on disk or 10.5 MB zipped. Reduced to the minimum library and only the English locale, translation and mapping data the build is 10 MB on disk or 4.6 MB zipped. Further optimizations possible. An app choosing to ship <span class="caps">ICU</span> with a reasonable number of supported language translations can expect a build of about 12 MB on disk or 6 MB zipped. The big decision is whether this is an acceptable size for downloads on Win, Mac and Android. (see below). | ||
Practically, there are three options depending on what features we need to use from <span class="caps">ICU</span>:<br /> 1) Only use the host api on Mac and Windows, use <span class="caps">ICU</span> as the host api on Linux, and | Practically, there are three options depending on what features we need to use from <span class="caps">ICU</span>:<br /> 1) Only use the host api on Mac and Windows, use <span class="caps">ICU</span> as the host api on Linux, and don't provide any features that are not common to all three api's.<br /> 2) Use Win/Mac host system api wherever possible, only require <span class="caps">ICU</span> for optional features where devs will be motivated to build and ship <span class="caps">ICU</span>.<br /> 3) Make <span class="caps">ICU</span> as a hard requirement to be always be built and shipped by all devs on Mac and Windows. | ||
Major questions: | Major questions: | ||
Line 78: | Line 107: | ||
* QTimeZone uses a lazy initialization that accepts any date, time and spec, validity is only checked when used | * QTimeZone uses a lazy initialization that accepts any date, time and spec, validity is only checked when used | ||
* isValid() does not take the time zone into account, only if QDate and QTime are individually valid | * isValid() does not take the time zone into account, only if QDate and QTime are individually valid | ||
* Date-only math functions (add day/month/year) only done in QDate, i.e. validity check and maths applied is on date only and | * Date-only math functions (add day/month/year) only done in QDate, i.e. validity check and maths applied is on date only and doesn't consider time and time zone, nor whether the result is valid in the tz. | ||
* Time math functions do use QDateTIme::isValid() and convert to <span class="caps">UTC</span> to calculate | * Time math functions do use QDateTIme::isValid() and convert to <span class="caps">UTC</span> to calculate | ||
* Changing spec (i.e. to <span class="caps">UTC</span> in calculations) calls mktime to calculate and validate, | * Changing spec (i.e. to <span class="caps">UTC</span> in calculations) calls mktime to calculate and validate, | ||
* The transition from Standard Time to Daylight Time (e.g. 2am becomes 3am) leaves a | * The transition from Standard Time to Daylight Time (e.g. 2am becomes 3am) leaves a 'hole' of 1 hour that should be considered invalid but isValid() returns true and the date and time maths functions are still applied | ||
It has been proposed to re-write QDateTime to internally store as an absolute msecs since epoch which would inherently solve many of these issues, but this would radically change the behaviour of QDateTime which currently treats the ymd/hms values as | It has been proposed to re-write QDateTime to internally store as an absolute msecs since epoch which would inherently solve many of these issues, but this would radically change the behaviour of QDateTime which currently treats the ymd/hms values as "fixed" and the time spec is used to interpret that value. This would mostly affect the default SystemTime spec where the system time zone can change underneath QDateTime causing the absolute <span class="caps">UTC</span> value to change. A considerable re-write would be required to keep the behaviour consistent. There is also the behaviour that you can store an invalid date but valid time in QDateTime, and later fix the date to be valid, which may not be possible if using a single qint64. Other likely effects would be: | ||
* Creation would be slower as has to validate and convert | * Creation would be slower as has to validate and convert | ||
Line 97: | Line 126: | ||
A further major issue is the Second Occurrence: | A further major issue is the Second Occurrence: | ||
* The transition from Daylight Time to Standard Time (e.g. 3am become 2am) has an hour that | * The transition from Daylight Time to Standard Time (e.g. 3am become 2am) has an hour that 'occurs' twice and is thus ambiguous, i.e. 2:30am. We currently have no api to indicate or set which occurrence. | ||
* Windows, Linux and Mac implementations of mktime have different assumptions for ambiguous times: Linux assumes first occurrence, Windows assumes second occurrence, Mac assumes first for about the first 40 minutes and second for the last 20 minutes (probably a bug). | * Windows, Linux and Mac implementations of mktime have different assumptions for ambiguous times: Linux assumes first occurrence, Windows assumes second occurrence, Mac assumes first for about the first 40 minutes and second for the last 20 minutes (probably a bug). | ||
* The mktime tm_isdst flag is not sufficient for certain scenarios | * The mktime tm_isdst flag is not sufficient for certain scenarios | ||
Line 124: | Line 153: | ||
===Common=== | ===Common=== | ||
<span class="caps">ICU</span> are notoriously bad at building libraries that can be reliably linked against, they offer no BC guarantees for C++, changing so names, dat files tightly coupled to library version, etc. For compatibility this leaves us to use the C api which lacks many of the advanced features in the C++ api that make using it desirable. C <span class="caps">API</span> additions to match can be requested and some have been added as a result, but old system versions shipped in <span class="caps">OSX</span> and Linux | <span class="caps">ICU</span> are notoriously bad at building libraries that can be reliably linked against, they offer no BC guarantees for C++, changing so names, dat files tightly coupled to library version, etc. For compatibility this leaves us to use the C api which lacks many of the advanced features in the C++ api that make using it desirable. C <span class="caps">API</span> additions to match can be requested and some have been added as a result, but old system versions shipped in <span class="caps">OSX</span> and Linux won't have these available. To use the C++ api would require strictly controlling the version of <span class="caps">ICU</span> linked to, i.e. building it ourselves. | ||
<span class="caps">ICU</span> respects the users locale code (e.g. en_GB) but | <span class="caps">ICU</span> respects the users locale code (e.g. en_GB) but doesn't use the host system data or the users custom settings (e.g. different date format), so <span class="caps">ICU</span> apps may not fully fit in with a users environment. This may especially be a problem on Windows where settings and behaviour are very different from the <span class="caps">POSIX</span> world. | ||
The default <span class="caps">ICU</span> data is fairly large, up to 21.3 MB on disk or 8.5 MB zipped, but not all data is actually required, such as code tables or translations for languages not supported by an app, and could be easily shrunk by apps to about 7MB on disk or 3.5 MB zipped. | The default <span class="caps">ICU</span> data is fairly large, up to 21.3 MB on disk or 8.5 MB zipped, but not all data is actually required, such as code tables or translations for languages not supported by an app, and could be easily shrunk by apps to about 7MB on disk or 3.5 MB zipped. | ||
Line 140: | Line 169: | ||
Work required to determine if sufficient host api functionality available for system locale, and if locale resource bundles can be opened to use for custom locales. | Work required to determine if sufficient host api functionality available for system locale, and if locale resource bundles can be opened to use for custom locales. | ||
For localization it seems unlikely the native <span class="caps">API</span> will provide a sufficient solution (especially on XP) so we need to make the build easier and the data smaller, or accept a lesser feature set for apps that | For localization it seems unlikely the native <span class="caps">API</span> will provide a sufficient solution (especially on XP) so we need to make the build easier and the data smaller, or accept a lesser feature set for apps that don't wish to ship <span class="caps">ICU</span>. This may not be an issue for most apps that don't require the more advanced locale features or custom locales. Those that do need the features will be more willing to make the effort. | ||
===Mac=== | ===Mac=== | ||
Line 154: | Line 183: | ||
===Linux=== | ===Linux=== | ||
<span class="caps">ICU</span> is available on all | <span class="caps">ICU</span> is available on all distro's and likely to always be installed due to other projects depending on it so is not a problem for availability or download size. Distro's are used to the issues involved with using <span class="caps">ICU</span> so it might not be unreasonable to make it a requirement to rebuild Qt whenever a major <span class="caps">ICU</span> update is made. In fact, this seems to be existing policy for other packages using <span class="caps">ICU</span>. | ||
===Android=== | ===Android=== | ||
Line 170: | Line 199: | ||
<span class="caps">QNX</span> ships <span class="caps">ICU</span>. Needs more investigation on how it is used and if there are any problems with linking to it directly instead of the native <span class="caps">API</span>. | <span class="caps">QNX</span> ships <span class="caps">ICU</span>. Needs more investigation on how it is used and if there are any problems with linking to it directly instead of the native <span class="caps">API</span>. | ||
BB10 ships <span class="caps">ICU</span> in firmware to use for <span class="caps">NDK</span> localization and Qt4 in firmware to use for | BB10 ships <span class="caps">ICU</span> in firmware to use for <span class="caps">NDK</span> localization and Qt4 in firmware to use for gui's (and thus uses old QLocale). Qt5 can be built and used, but is not yet a standard install in firmware. This means Qt5 can use the system <span class="caps">ICU</span> as the locale back-end, i.e. same as Linux. Initially will only be able to use the C api, but once both are in firmware it will always be a monolithic system build so can probably use the C++ api. | ||
===QtWebKit=== | ===QtWebKit=== | ||
Line 190: | Line 219: | ||
It seems clear we cannot rely on the system <span class="caps">ICU</span> on Mac, and there is no system install on Windows, which swings the platform balance to 2 to 1 on devs having to build and ship <span class="caps">ICU</span> themselves. While forcing a self-build is extra work for devs, it does have the benefit of allowing us to use the C++ api. | It seems clear we cannot rely on the system <span class="caps">ICU</span> on Mac, and there is no system install on Windows, which swings the platform balance to 2 to 1 on devs having to build and ship <span class="caps">ICU</span> themselves. While forcing a self-build is extra work for devs, it does have the benefit of allowing us to use the C++ api. | ||
Practically, there are three options depending on what features we choose to use from <span class="caps">ICU</span>:<br /> 1) Only use <span class="caps">ICU</span> on Linux for the host system localization, use the host api on Mac and Windows, and | Practically, there are three options depending on what features we choose to use from <span class="caps">ICU</span>:<br /> 1) Only use <span class="caps">ICU</span> on Linux for the host system localization, use the host api on Mac and Windows, and don't provide any advanced features that are not common to all three api's. The same would apply to Code Tables.<br /> 2) Keep <span class="caps">ICU</span> optional on Win/Mac, use Win/Mac host system api wherever possible and only require <span class="caps">ICU</span> for optional advanced features when devs will be motivated to build and ship <span class="caps">ICU</span>.<br /> 3) Make <span class="caps">ICU</span> a hard requirement to be built and shipped by all devs on Mac and Windows, and require Linux devs to either build and ship themselves or use the system install and always rebuild Qt on system <span class="caps">ICU</span> upgrades. | ||
Choosing 1) denies advanced features and | Choosing 1) denies advanced features and doesn't solve the QtWebKit issue. In either of 2) or 3) devs will be faced with the need to build and ship <span class="caps">ICU</span> themselves and we need to make this easy and lightweight for them. Shipping all of <span class="caps">ICU</span> inside qtbase/3rdparty with a default config is not desirable, but nor can we expect all devs to suddenly become experts on building <span class="caps">ICU</span>. We should provide a simple build script that configures and enables those features in <span class="caps">ICU</span> that Qt uses, and allow the devs to choose what locales and code tables to ship. | ||
One advantage of requiring our own copy of <span class="caps">ICU</span> is we can set a minimum version that has all the features we want to use on all platforms, and can use the C++ <span class="caps">API</span>. | One advantage of requiring our own copy of <span class="caps">ICU</span> is we can set a minimum version that has all the features we want to use on all platforms, and can use the C++ <span class="caps">API</span>. | ||
Line 216: | Line 245: | ||
Data resources that are not required can be removed to reduce the download size. This is done at build time by either directly modifying the original .mk files, or more practically by saving the modified options in new reslocal.mk files which the <span class="caps">ICU</span> build system will then use to override the original settings. Another option is to manually use the online data customiser to build a custom .dat file, but this is a manual interactive process not easily automated and may be prone to human error. | Data resources that are not required can be removed to reduce the download size. This is done at build time by either directly modifying the original .mk files, or more practically by saving the modified options in new reslocal.mk files which the <span class="caps">ICU</span> build system will then use to override the original settings. Another option is to manually use the online data customiser to build a custom .dat file, but this is a manual interactive process not easily automated and may be prone to human error. | ||
Most data is the mapping conversion tables, removing these will have the greatest effect. <span class="caps">ICU</span> notes | Most data is the mapping conversion tables, removing these will have the greatest effect. <span class="caps">ICU</span> notes "<span class="caps">ICU</span> provides full internationalization functionality without any conversion table data. The common library contains code to handle several important encodings algorithmically: US-<span class="caps">ASCII</span>, <span class="caps">ISO</span>-8859-1, <span class="caps">UTF</span>-7/8/16/32, <span class="caps">SCSU</span>, <span class="caps">BOCU</span>-1, <span class="caps">CESU</span>-8, and <span class="caps">IMAP</span>-mailbox-name (i.e., US-<span class="caps">ASCII</span>, <span class="caps">ISO</span>-8859-1, and all Unicode charsets; see source/data/mappings/convrtrs.txt for the current list)." As such even if Qt uses <span class="caps">ICU</span> for conversions we may not need all/any of the conversion tables. | ||
Locale data takes a small proportion, but may also be reduced by removing uncommon locales, or allowing devs to choose which they want. | Locale data takes a small proportion, but may also be reduced by removing uncommon locales, or allowing devs to choose which they want. | ||
Line 303: | Line 332: | ||
| 9.5% | | 9.5% | ||
|- | |- | ||
| Language & | | Language & Region Names | ||
| 2.8 | | 2.8 | ||
| 0.9 | | 0.9 | ||
Line 313: | Line 342: | ||
| 7% | | 7% | ||
|- | |- | ||
| Currency Names & | | Currency Names & Plurals | ||
| 1.9 | | 1.9 | ||
| 0.6 | | 0.6 | ||
Line 333: | Line 362: | ||
| 1.2% | | 1.2% | ||
|- | |- | ||
| String Preparation (<span class="caps">RFC</span> | | String Preparation (<span class="caps">RFC</span>'s) | ||
| 0.2 | | 0.2 | ||
| 0.1 | | 0.1 | ||
Line 352: | Line 381: | ||
See http://thebugfreeblog.blogspot.co.uk/2013/05/cross-building-icu-for-applications-on.html | See http://thebugfreeblog.blogspot.co.uk/2013/05/cross-building-icu-for-applications-on.html | ||
export <span class="caps">CPPFLAGS</span>= | export <span class="caps">CPPFLAGS</span>="-DU_USING_ICU_NAMESPACE=0 -DU_CHARSET_IS_UTF8=1 -<span class="caps">DUNISTR</span>_FROM_CHAR_EXPLICIT=explicit -<span class="caps">DUNISTR</span>_FROM_STRING_EXPLICIT=explicit -DU_NO_DEFAULT_INCLUDE_UTF_HEADERS=1"<br /> ./runConfigureICU Linux —with-library-suffix=qt —disable-draft —disable-extras —disable-icuio —disable-layout —disable-test —disable-samples | ||
===QtWebKit=== | ===QtWebKit=== | ||
Line 374: | Line 403: | ||
! Used in WebKit By | ! Used in WebKit By | ||
|- | |- | ||
| | | <unicode/locid.h> | ||
| C++ | | C++ | ||
| Locale | | Locale | ||
| skia, chromium | | skia, chromium | ||
|- | |- | ||
| | | <unicode/normlzr.h> | ||
| C++ | | C++ | ||
| Normalization | | Normalization | ||
| freetype, harfbuzz, skia | | freetype, harfbuzz, skia | ||
|- | |- | ||
| | | <unicode/uniset.h> | ||
| C++ | | C++ | ||
| Sets of Unicode Code Points and Strings | | Sets of Unicode Code Points and Strings | ||
| chromium | | chromium | ||
|- | |- | ||
| | | <unicode/ubrk.h> | ||
| C | | C | ||
| Text Boundary Analysis (Break Iteration) | | Text Boundary Analysis (Break Iteration) | ||
| text | | text | ||
|- | |- | ||
| | | <unicode/uchar.h> | ||
| C | | C | ||
| Unicode Character Properties and Names | | Unicode Character Properties and Names | ||
| win, harfbuzz, wx, chromium, wtf | | win, harfbuzz, wx, chromium, wtf | ||
|- | |- | ||
| | | <unicode/ucnv_cb.h> | ||
| C | | C | ||
| Codepage Conversion and Unicode Text Compression | | Codepage Conversion and Unicode Text Compression | ||
| text, wtf | | text, wtf | ||
|- | |- | ||
| | | <unicode/ucnv.h> | ||
| C | | C | ||
| Codepage Conversion and Unicode Text Compression | | Codepage Conversion and Unicode Text Compression | ||
| text, wtf | | text, wtf | ||
|- | |- | ||
| | | <unicode/udat.h> | ||
| C | | C | ||
| Date api | | Date api | ||
| JavaScriptCore/runtime, text | | JavaScriptCore/runtime, text | ||
|- | |- | ||
| | | <unicode/udatpg.h> | ||
| C | | C | ||
| Date Pattern Generator | | Date Pattern Generator | ||
| text | | text | ||
|- | |- | ||
| | | <unicode/uidna.h> | ||
| C | | C | ||
| International Domain Names in Applications | | International Domain Names in Applications | ||
| WebCore/platform/KURL.cpp, wtf | | WebCore/platform/KURL.cpp, wtf | ||
|- | |- | ||
| | | <unicode/uloc.h> | ||
| C | | C | ||
| Locales | | Locales | ||
| text | | text | ||
|- | |- | ||
| | | <unicode/unorm.h> | ||
| C | | C | ||
| Normalization | | Normalization | ||
| graphics/SurrogatePairAwareTextIterator.cpp, win, wx, chromium, text | | graphics/SurrogatePairAwareTextIterator.cpp, win, wx, chromium, text | ||
|- | |- | ||
| | | <unicode/unum.h> | ||
| C | | C | ||
| Number Formatting | | Number Formatting | ||
| text | | text | ||
|- | |- | ||
| | | <unicode/uscript.h> | ||
| C | | C | ||
| Unicode Character Properties and Names | | Unicode Character Properties and Names | ||
| chromium, wtf | | chromium, wtf | ||
|- | |- | ||
| | | <unicode/usearch.h> | ||
| C | | C | ||
| String Searching | | String Searching | ||
| WebCore/editing | | WebCore/editing | ||
|- | |- | ||
| | | <unicode/uset.h> | ||
| C | | C | ||
| Sets of Unicode Code Points and Strings | | Sets of Unicode Code Points and Strings | ||
| WebCore/editing | | WebCore/editing | ||
|- | |- | ||
| | | <unicode/ustring.h> | ||
| C | | C | ||
| Strings and Character Iteration | | Strings and Character Iteration | ||
| blackberry, wtf | | blackberry, wtf | ||
|- | |- | ||
| | | <unicode/utf16.h> | ||
| C | | C | ||
| Strings and Character Iteration | | Strings and Character Iteration | ||
| blackberry, wx, linux, wtf | | blackberry, wx, linux, wtf | ||
|- | |- | ||
| | | <unicode/utypes.h> | ||
| C | | C | ||
| Basic Types and Constants | | Basic Types and Constants |
Latest revision as of 17:26, 6 January 2017
This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine. Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean. |
WIP
Table of Content
Agenda
- Review decision on using ICU everywhere in Qt
- Discuss QTimeZone integration into QDateTime: initialization, validation and daylight saving transitions
Minutes
Take by David Faure
QSystemLocale picks up the user settings (bypassing ICU, which doesn't do that).
So it needs platform backends to do that.
Same for the user-selected timezone, etc.
=> ICU is really just the database.
We need to complete that code, to get all settings on all OSes.
ICU data is 26 MB on disk (on Windows). The bulk is timezones. Lots of translations. 4.6 MB with just the english locale and language.
ICU4C lib = 5MB on top.
Idea from Thiago: QLocale – basic, based on host apis Something more complete based on ICU -> in a separate module Could be done with QCollator, calendering and other future stuff, but not very consistent
Idea from Lars: a stripped ICU. Translations would come from Qt po files.
Another option: load ICU dynamically, and use system apis if it's not available.
Dropped idea: a plugin (loaded with native APIs, no QString), which would also exist with
minimal, small, and full versions. Creates a deployment problem.
Conclusions:
Mac: we'll use the Mac API wrapper
Android: TODO: check if we can use the ICU data files from ICU4J (same as the ones from ICU4C) TODO: check if we can use that data, even if the lib isn't available. It should be the same version of ICU though! Or we could use JNI….. (everyone is horrified by the idea though).
Idea from Lars: an ICU-compatible replacement API, that can be shipped instead of ICU to save size.
QtCore uses 26 symbols from ICU.
So the user could choose which ICU to use: 1) minimal (just C), 2) small (C and one selected locale?), 3) full.
Whenever using QtWebKit, the full one is required. It's really mutually exclusive (webkit uses 85 symbols from icu)
ICU and Qt
At QtCS 2012 it was decided to migrate to using ICU for all localization services to reduce our own code and data, and possibly for code conversion tables, effectively making it a hard requirement for Qt5. Since then a number of technical and political objections have been raised which need to be addressed. This session is to discuss the problems and try come up with a solution.
Primary issues:
- ICU ignores host data and any user custom settings, so may not appear 'native'
- BC issues with using system libraries limit us to using the C api which lacks features we may need
- Mac doesn't ship system library headers, App Store bans direct linking to libicu, out-dated system versions
- Complaints from Windows devs that ICU download is too big to ship and has no debug version, but too hard to build / shrink the build themselves
- Android doesn't guarantee ICU4C will be installed(?), but offers no other NDK localization option(?)
- Tizen also doesn't ship ICU headers or allow linking to system ICU in its app store
- QtWebKit has hard requirement that is not easily removed
This essentially means we must either use only native api on Win and Mac, or ship our own minimal version of ICU.
A default ICU 50.1 build with full data is 26.5 MB on disk or 10.5 MB zipped. Reduced to the minimum library and only the English locale, translation and mapping data the build is 10 MB on disk or 4.6 MB zipped. Further optimizations possible. An app choosing to ship ICU with a reasonable number of supported language translations can expect a build of about 12 MB on disk or 6 MB zipped. The big decision is whether this is an acceptable size for downloads on Win, Mac and Android. (see below).
Practically, there are three options depending on what features we need to use from ICU:
1) Only use the host api on Mac and Windows, use ICU as the host api on Linux, and don't provide any features that are not common to all three api's.
2) Use Win/Mac host system api wherever possible, only require ICU for optional features where devs will be motivated to build and ship ICU.
3) Make ICU as a hard requirement to be always be built and shipped by all devs on Mac and Windows.
Major questions:
- Are host system api sufficient for requirements? Mac yes for localization as thin wrapper to ICU, WinRT appears to be modelled on ICU, Win32 needs research but seems doubtful. Not clear if Windows allows opening resource files for non-system/custom locales.
- Android / BB10 / QNX / Tizen details?
Side note: The Chromium/Blink project has debated these same issues and decided to always build and ship their own version of ICU on all platforms including Linux and Android, wrapped in a thin abstraction layer.
It is proposed to follow option 2) until such time as we need features only ICU or the the C++ api can provide. An extension of option 3) is to also force our own build on Linux which would allow us to use the C++ api.
- New build script in qtbase/3rdparty to checkout, configure and build minimal required ICU as part of qtbase standard build system
- Build script able to be customized to choose what locales and translations to ship
- Localization to always use host api for system locale, any features needing ICU must be optional build-time flag
- Script detects if ICU features are needed, Win/Mac/iOS/Android build and link own copy of libicu, Linux/QNX defaults to system library but can choose own copy if needed
- Only use ICU C api for now, but require a recent enough version on all platforms to be useful, if not available from system then must build own
- Minimal non-ICU C locale for embedded if required?
QTimeZone / QDateTime integration issues
The current implementation of QDateTime with the system time zone has a number of implementation issues around initialization, validity checking, and maths that will also affect QTimeZone so should have their behaviour defined or fixed before QTimeZone is integrated.
- QTimeZone uses a lazy initialization that accepts any date, time and spec, validity is only checked when used
- isValid() does not take the time zone into account, only if QDate and QTime are individually valid
- Date-only math functions (add day/month/year) only done in QDate, i.e. validity check and maths applied is on date only and doesn't consider time and time zone, nor whether the result is valid in the tz.
- Time math functions do use QDateTIme::isValid() and convert to UTC to calculate
- Changing spec (i.e. to UTC in calculations) calls mktime to calculate and validate,
- The transition from Standard Time to Daylight Time (e.g. 2am becomes 3am) leaves a 'hole' of 1 hour that should be considered invalid but isValid() returns true and the date and time maths functions are still applied
It has been proposed to re-write QDateTime to internally store as an absolute msecs since epoch which would inherently solve many of these issues, but this would radically change the behaviour of QDateTime which currently treats the ymd/hms values as "fixed" and the time spec is used to interpret that value. This would mostly affect the default SystemTime spec where the system time zone can change underneath QDateTime causing the absolute UTC value to change. A considerable re-write would be required to keep the behaviour consistent. There is also the behaviour that you can store an invalid date but valid time in QDateTime, and later fix the date to be valid, which may not be possible if using a single qint64. Other likely effects would be:
- Creation would be slower as has to validate and convert
- Accessing most commonly used functions would be slower, e.g. caliing dt.date().day or dt.time().hour()
- Maths and conversion functions would be faster and simpler and more accurate
- Memory footprint would be reduced by one-third
If we keep storage in QDate/QTime format we have to ensure validity is checked properly. This solution is a lot less code change and keeps current behaviour, but
- QDateTime::isValid() must check if valid in tz, i.e. call mktime the first time called then cache result in QDateTImePrivate::Spec
- All date-only maths needs to be converted to UTC first then converted back, same as for time
A further major issue is the Second Occurrence:
- The transition from Daylight Time to Standard Time (e.g. 3am become 2am) has an hour that 'occurs' twice and is thus ambiguous, i.e. 2:30am. We currently have no api to indicate or set which occurrence.
- Windows, Linux and Mac implementations of mktime have different assumptions for ambiguous times: Linux assumes first occurrence, Windows assumes second occurrence, Mac assumes first for about the first 40 minutes and second for the last 20 minutes (probably a bug).
- The mktime tm_isdst flag is not sufficient for certain scenarios
The current time zone patches have api for setting and reading the occurrence, but issues with mktime have prevented working code so far.
Development plan:
- Re-submit patches for offsetFromUtc and cleaning up format/parse code
- Implement chosen solution for QDateTIme internals, other clean-ups
- Implement second occurrence support for SystemTime only
- Re-submit QTimeZone patches
Detailed notes on ICU in Qt5
Current use of ICU in Qt5
- QtWebKit – required on all platforms for localization and text layout.
- QtCore / QIcuCodec – private, optional
- QtCore / QCollator – private, optional
- QtCore / QLocale for toUpper() and toLower() – private, optional
- sqlite3?
Issues with ICU
Common
ICU are notoriously bad at building libraries that can be reliably linked against, they offer no BC guarantees for C++, changing so names, dat files tightly coupled to library version, etc. For compatibility this leaves us to use the C api which lacks many of the advanced features in the C++ api that make using it desirable. C API additions to match can be requested and some have been added as a result, but old system versions shipped in OSX and Linux won't have these available. To use the C++ api would require strictly controlling the version of ICU linked to, i.e. building it ourselves.
ICU respects the users locale code (e.g. en_GB) but doesn't use the host system data or the users custom settings (e.g. different date format), so ICU apps may not fully fit in with a users environment. This may especially be a problem on Windows where settings and behaviour are very different from the POSIX world.
The default ICU data is fairly large, up to 21.3 MB on disk or 8.5 MB zipped, but not all data is actually required, such as code tables or translations for languages not supported by an app, and could be easily shrunk by apps to about 7MB on disk or 3.5 MB zipped.
Windows
See http://thread.gmane.org/gmane.comp.lib.qt.devel/9226
ICU is not shipped with Windows so all apps need to build and distribute their own copy of ICU including data. Devs have complained that ICU is too big (!) and too hard to build.
A binary download of 11.4 MB is available from ICU, but only for mvsc10 and not debug versions which causes issues.
Work required to determine if sufficient host api functionality available for system locale, and if locale resource bundles can be opened to use for custom locales.
For localization it seems unlikely the native API will provide a sufficient solution (especially on XP) so we need to make the build easier and the data smaller, or accept a lesser feature set for apps that don't wish to ship ICU. This may not be an issue for most apps that don't require the more advanced locale features or custom locales. Those that do need the features will be more willing to make the effort.
Mac
ICU ships as standard on OSX and iOS, with the official API classes effectively thin wrappers around ICU that allow for user customisations. Shipped versions of ICU tend to be rather old, and the headers are not included to discourage the direct use of ICU. Currently Qt5 requires installing MacPorts and linking to their version of ICU, but this is a bad solution as it is not portable or distributable (it also causes build problems if Macports Qt4 is also installed). It is possible to download the headers from opensource.apple.com with some effort and use those instead (WebKit, Chrome and others do this by including a copy of the headers). However apps are rejected from the App Store if they directly link to ICU which effectively rules out using the system ICU for anything on iOS and thus for simplicity on OSX too. It is not clear if shipping a self-built copy of ICU is acceptable to the App Store, but the extra 20Mb added to the download is not likely to be acceptable to iOS developers so would need to be trimmed down.
ICU provides a 64bit binary download of 11Mb.
For localization the native API will probably be sufficient. Code tables require investigation.
QtWebKit is not permitted on iOS by the App Store rules, apps must use the native WebKit install. Therefore iOS does not need to be considered in any QtWebKit solution.
Linux
ICU is available on all distro's and likely to always be installed due to other projects depending on it so is not a problem for availability or download size. Distro's are used to the issues involved with using ICU so it might not be unreasonable to make it a requirement to rebuild Qt whenever a major ICU update is made. In fact, this seems to be existing policy for other packages using ICU.
Android
Android ships ICU? Or just the Java version by default? Needs more investigation on how it is used and if there are any problems with linking to it directly instead of the native API.
ICU4C is not a standard part of Android, but is supported in Android External and builds fine. Appears to be no native C/C++ api to use in NDK, only Java native api. Not yet clear if should use Android src repo or ICU master repo. Appears we will need to build and ship our own copy.
Android repo at https://android.googlesource.com/platform/external/icu4c but doc at http://source.android.com/source/submit-patches.html#icu4c makes it clear upstream is considered the master.
See https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/eSiHBND2rAQ/X9LyMHImNjgJ for an interesting discussion on using ICU in WebKit / Blink / Android which seems to suggest ICU system will become standard install?
BB10 / QNX
QNX ships ICU. Needs more investigation on how it is used and if there are any problems with linking to it directly instead of the native API.
BB10 ships ICU in firmware to use for NDK localization and Qt4 in firmware to use for gui's (and thus uses old QLocale). Qt5 can be built and used, but is not yet a standard install in firmware. This means Qt5 can use the system ICU as the locale back-end, i.e. same as Linux. Initially will only be able to use the C api, but once both are in firmware it will always be a monolithic system build so can probably use the C++ api.
QtWebKit
WebKit provides a localization, text layout and string encoding abstraction layer. WebKit ports such as QtWebKit can provide their own backend but most choose to use the existing ICU back-end for convenience. QtWebKit4 apparently used to use QLocale/QString but switched to ICU for Qt5? This means QtWebKit needs and uses ICU on all platforms and so may not always properly fit in, whereas other system-provided WebKit ports may actually use the native api and so fit in better. Need to determine exactly what QtWebKit uses from ICU and whether current approach is still best. Also an issue that by using ICU for localization may get different results than QLocale may provide for the rest of the app.
WebKit / QtWebKit has 4 copies of the ICU headers included in its source tree, used to build on Mac 10.4.
WebKit / QtWebKit mostly uses the ICU C api, but does occasionally use the C++ api in port specific code.
See https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/eSiHBND2rAQ/X9LyMHImNjgJ for an interesting discussion on using ICU in WebKit / Blink.
Build appears to only link against core and i18n libraries. See bottom for detailed breakdown of ICU includes used in WebKit.
QtWebKit is not permitted on iOS by the App Store rules, apps must use the native WebKit install. Therefore iOS does not need to be considered in any QtWebKit solution.
Possible solutions
It seems clear we cannot rely on the system ICU on Mac, and there is no system install on Windows, which swings the platform balance to 2 to 1 on devs having to build and ship ICU themselves. While forcing a self-build is extra work for devs, it does have the benefit of allowing us to use the C++ api.
Practically, there are three options depending on what features we choose to use from ICU:
1) Only use ICU on Linux for the host system localization, use the host api on Mac and Windows, and don't provide any advanced features that are not common to all three api's. The same would apply to Code Tables.
2) Keep ICU optional on Win/Mac, use Win/Mac host system api wherever possible and only require ICU for optional advanced features when devs will be motivated to build and ship ICU.
3) Make ICU a hard requirement to be built and shipped by all devs on Mac and Windows, and require Linux devs to either build and ship themselves or use the system install and always rebuild Qt on system ICU upgrades.
Choosing 1) denies advanced features and doesn't solve the QtWebKit issue. In either of 2) or 3) devs will be faced with the need to build and ship ICU themselves and we need to make this easy and lightweight for them. Shipping all of ICU inside qtbase/3rdparty with a default config is not desirable, but nor can we expect all devs to suddenly become experts on building ICU. We should provide a simple build script that configures and enables those features in ICU that Qt uses, and allow the devs to choose what locales and code tables to ship.
One advantage of requiring our own copy of ICU is we can set a minimum version that has all the features we want to use on all platforms, and can use the C++ API.
Localization
The QTimeZone code provides a template for the solution. Keep the concept of a default system locale that uses the host facilities directly, but at compile time can determine if want to use ICU instead. This means maintaining more code but seems the only practical solution.
On Linux: Use ICU for system and custom locale.
On Mac: Use standard API for system and custom locale.
On Windows: Work required to determine if sufficient functionality available for system locale, and if locale resource bundles can be opened for custom locales, otherwise will have to use ICU.
Data size / build
A number of options are available to reduce the size of both the library and the data, by not building some features and reducing the data shipped for those features that are enabled.
Work was started by Kai to determine what data resources were required and not required, but no results have been published.
The data can be built in 2 ways:
1) The default is built as a shared data library that is linked to and loaded alongside the main ICU library. This library is generated from a copy of the data files in the source tree. This is the fastest option but means the library must be updated if the data is to be updated, and is not portable across platforms.
2) The shared data library is built as a stub and the data is loaded from a .dat file located in a defined directory. The .dat file is specific to a given major and minor release, but maintains BC for point releases and is portable across some platforms that have the same endianess.
Data is mmapped so memory usage is not affected by how much data is shipped.
Features can be disabled at build time by either editing the uconfig.h, uversion.h and utypes.h files, or more practically by passing -D flags.
Data resources that are not required can be removed to reduce the download size. This is done at build time by either directly modifying the original .mk files, or more practically by saving the modified options in new reslocal.mk files which the ICU build system will then use to override the original settings. Another option is to manually use the online data customiser to build a custom .dat file, but this is a manual interactive process not easily automated and may be prone to human error.
Most data is the mapping conversion tables, removing these will have the greatest effect. ICU notes "ICU provides full internationalization functionality without any conversion table data. The common library contains code to handle several important encodings algorithmically: US-ASCII, ISO-8859-1, UTF-7/8/16/32, SCSU, BOCU-1, CESU-8, and IMAP-mailbox-name (i.e., US-ASCII, ISO-8859-1, and all Unicode charsets; see source/data/mappings/convrtrs.txt for the current list)." As such even if Qt uses ICU for conversions we may not need all/any of the conversion tables.
Locale data takes a small proportion, but may also be reduced by removing uncommon locales, or allowing devs to choose which they want.
Collation data uses a significant amount of data. Removing the Asian collation files would greatly reduce this but is possibly undesirable. Another option is to remove the tailoring rule strings from which the data is built which are rarely used at runtime.
Build sizes
Build | Disk Size | Zipped Size |
---|---|---|
Default full build, full data | 26.5 MB | 10.5 MB |
Core build, full data | 25.9 MB | 10.3 MB |
Core build, all locales, only en translations | 11.2 MB | 5.0 MB |
Core build, only en locale and translations | 10.0 MB | 4.6 MB |
Core build excludes the optional I/O, Font Layout and Tool Utility libraries. Difference of 0.2 MB zipped size means little to be gained form code/functionality reductions, but other flags may further reduce size.
Library | Linux Filename | Linux Size |
---|---|---|
Common Library | libicuuc | 1.8 MB |
i18n Library | libicu18n | 2.6 MB |
Data Library | libicudata | 21.3 MB |
I/O Library (optional) | libicuio | 66 KB |
Font Layout Library (optional) | libicule | 440 KB |
Font Layout Extension Library (optional) | libiculx | 66 KB |
Tool Utility Library (optional) | libicutu | 203 KB |
Data | Disk Size | Zipped Size | Zipped % |
---|---|---|---|
Total Data | 21.3 MB | 8.5 MB | 100% |
Code Table Mappings | 4.4 | 2.3 | 27% |
Collation Rules | 3.3 | 0.8 | 9.5% |
Language & Region Names | 2.8 | 0.9 | 10.5% |
Time Zone Names | 2.1 | 0.6 | 7% |
Currency Names & Plurals | 1.9 | 0.6 | 7% |
Locale Formats | 1.2 | 0.4 | 5% |
Transliteration Rules and Names | 0.6 | 0.2 | 2.4 % |
Rule Based Number Formatting | 0.3 | 0.1 | 1.2% |
String Preparation (RFC's) | 0.2 | 0.1 | 1.2% |
Root data? | 4.5 | 2.5 | 29.5% |
Proposal:
1) Include a new build script in qtbase/3rdparty/icu
2) Script is run as part of configure depending on platform and flags
3) Script downloads the src tarball recommended for a given version of Qt
4) Script defaults to building only those features used by Qt on a given platform and removes data resources that are not needed by most clients.
5) Script can either be manually modified to include or excluded more features and data, or can interactively ask during configure step.
6) Script writes modified data options to icu/src/data/*/reslocal.mk build files which override the main *.mk files
7) Script runs configure with build-time options required
8) Build happens as part of normal Qt build.
Suggested flags from ICU readme:
U_USING_ICU_NAMESPACE=0
U_CHARSET_IS_UTF8=1 – On UTF8 platforms
UNISTR_FROM_CHAR_EXPLICIT=explicit
UNISTR_FROM_STRING_EXPLICIT=explicit
U_NO_DEFAULT_INCLUDE_UTF_HEADERS=1
U_HIDE_DRAFT_API
U_HIDE_INTERNAL_API
U_HIDE_SYSTEM_API
—with-library-suffix – Add Qt as a suffix to name
Other options available:
—with-data-packaging=archive – To use .dat file instead
—enable-static —disable-shared – For static builds
See http://thebugfreeblog.blogspot.co.uk/2013/05/cross-building-icu-for-applications-on.html
export CPPFLAGS="-DU_USING_ICU_NAMESPACE=0 -DU_CHARSET_IS_UTF8=1 -DUNISTR_FROM_CHAR_EXPLICIT=explicit -DUNISTR_FROM_STRING_EXPLICIT=explicit -DU_NO_DEFAULT_INCLUDE_UTF_HEADERS=1"
./runConfigureICU Linux —with-library-suffix=qt —disable-draft —disable-extras —disable-icuio —disable-layout —disable-test —disable-samples
QtWebKit
Two options:
1) Continue using ICU, use new QtCore built copy of ICU, assumes iOS will accept shipping extra copy of ICU.
2) Write new platform back-end using new Qt classes for locale and text layout, but this is a lot of work.
Option 1) is the only practical solution until such time as QtCore can provide all the required functions. The locale functions will come as a result of the new QLocale ICU backend and wrapper classes, and as the design matches ICU closely should be straightforward to implement. The difficulty of the text layout and encoding back-ends is an open question.
ICU includes in QtWebKit
ICU Backend in qtwebkit/Source/WebCore/platform/text/
LineBreakIteratorPoolICU.h
LocaleICU.h/.cpp
LocaleToScriptMappingICU.cpp
TextBreakIteratorICU.h/.cpp
TextCodecICU.h/.cpp
TextEncodingDetector.cpp
ICU Backend in Source/WTF/wtf/:
url/src/URLCanonICU.cpp
unicode/icu/UnicodeIcu.h
unicode/icu/CollatorICU.cpp
unicode/qt4/UnicodeQt4.h
All ICU includes used in QtWebKit source tree, not all are built by Qt port:
Include | Language | Function | Used in WebKit By |
---|---|---|---|
<unicode/locid.h> | C++ | Locale | skia, chromium |
<unicode/normlzr.h> | C++ | Normalization | freetype, harfbuzz, skia |
<unicode/uniset.h> | C++ | Sets of Unicode Code Points and Strings | chromium |
<unicode/ubrk.h> | C | Text Boundary Analysis (Break Iteration) | text |
<unicode/uchar.h> | C | Unicode Character Properties and Names | win, harfbuzz, wx, chromium, wtf |
<unicode/ucnv_cb.h> | C | Codepage Conversion and Unicode Text Compression | text, wtf |
<unicode/ucnv.h> | C | Codepage Conversion and Unicode Text Compression | text, wtf |
<unicode/udat.h> | C | Date api | JavaScriptCore/runtime, text |
<unicode/udatpg.h> | C | Date Pattern Generator | text |
<unicode/uidna.h> | C | International Domain Names in Applications | WebCore/platform/KURL.cpp, wtf |
<unicode/uloc.h> | C | Locales | text |
<unicode/unorm.h> | C | Normalization | graphics/SurrogatePairAwareTextIterator.cpp, win, wx, chromium, text |
<unicode/unum.h> | C | Number Formatting | text |
<unicode/uscript.h> | C | Unicode Character Properties and Names | chromium, wtf |
<unicode/usearch.h> | C | String Searching | WebCore/editing |
<unicode/uset.h> | C | Sets of Unicode Code Points and Strings | WebCore/editing |
<unicode/ustring.h> | C | Strings and Character Iteration | blackberry, wtf |
<unicode/utf16.h> | C | Strings and Character Iteration | blackberry, wx, linux, wtf |
<unicode/utypes.h> | C | Basic Types and Constants | text |
ICU Documentation
http://site.icu-project.org/charts/charset
http://site.icu-project.org/charts/icu4c-footprint
http://userguide.icu-project.org/packaging
http://userguide.icu-project.org/design
http://userguide.icu-project.org/design#TOC-ICU-Binary-Compatibility:-Using-ICU-as-an-Operating-System-Level-Library
http://userguide.icu-project.org/icudata
http://apps.icu-project.org/datacustom/
http://www.icu-project.org/docs/demo/datacustom_help.html
http://source.icu-project.org/repos/icu/icu/trunk/readme.html