Ejemplo n.º 1
0
status_t
BLanguage::GetNativeName(BString& name) const
{
	UnicodeString string;
	fICULocale->getDisplayName(*fICULocale, string);
	string.toTitle(NULL, *fICULocale);

	name.Truncate(0);
	BStringByteSink converter(&name);
	string.toUTF8(converter);

	return B_OK;
}
void
StringCaseTest::TestCasingImpl(const UnicodeString &input,
                               const UnicodeString &output,
                               int32_t whichCase,
                               void *iter, const char *localeID, uint32_t options) {
    // UnicodeString
    UnicodeString result;
    const char *name;
    Locale locale(localeID);

    result=input;
    switch(whichCase) {
    case TEST_LOWER:
        name="toLower";
        result.toLower(locale);
        break;
    case TEST_UPPER:
        name="toUpper";
        result.toUpper(locale);
        break;
#if !UCONFIG_NO_BREAK_ITERATION
    case TEST_TITLE:
        name="toTitle";
        result.toTitle((BreakIterator *)iter, locale, options);
        break;
#endif
    case TEST_FOLD:
        name="foldCase";
        result.foldCase(options);
        break;
    default:
        name="";
        break; // won't happen
    }
    if(result!=output) {
        dataerrln("error: UnicodeString.%s() got a wrong result for a test case from casing.res", name);
    }
#if !UCONFIG_NO_BREAK_ITERATION
    if(whichCase==TEST_TITLE && options==0) {
        result=input;
        result.toTitle((BreakIterator *)iter, locale);
        if(result!=output) {
            dataerrln("error: UnicodeString.toTitle(options=0) got a wrong result for a test case from casing.res");
        }
    }
#endif

    // UTF-8
    char utf8In[100], utf8Out[100];
    int32_t utf8InLength, utf8OutLength, resultLength;
    UChar *buffer;

    IcuTestErrorCode errorCode(*this, "TestCasingImpl");
    LocalUCaseMapPointer csm(ucasemap_open(localeID, options, errorCode));
#if !UCONFIG_NO_BREAK_ITERATION
    if(iter!=NULL) {
        // Clone the break iterator so that the UCaseMap can safely adopt it.
        UBreakIterator *clone=ubrk_safeClone((UBreakIterator *)iter, NULL, NULL, errorCode);
        ucasemap_setBreakIterator(csm.getAlias(), clone, errorCode);
    }
#endif

    u_strToUTF8(utf8In, (int32_t)sizeof(utf8In), &utf8InLength, input.getBuffer(), input.length(), errorCode);
    switch(whichCase) {
    case TEST_LOWER:
        name="ucasemap_utf8ToLower";
        utf8OutLength=ucasemap_utf8ToLower(csm.getAlias(),
                    utf8Out, (int32_t)sizeof(utf8Out),
                    utf8In, utf8InLength, errorCode);
        break;
    case TEST_UPPER:
        name="ucasemap_utf8ToUpper";
        utf8OutLength=ucasemap_utf8ToUpper(csm.getAlias(),
                    utf8Out, (int32_t)sizeof(utf8Out),
                    utf8In, utf8InLength, errorCode);
        break;
#if !UCONFIG_NO_BREAK_ITERATION
    case TEST_TITLE:
        name="ucasemap_utf8ToTitle";
        utf8OutLength=ucasemap_utf8ToTitle(csm.getAlias(),
                    utf8Out, (int32_t)sizeof(utf8Out),
                    utf8In, utf8InLength, errorCode);
        break;
#endif
    case TEST_FOLD:
        name="ucasemap_utf8FoldCase";
        utf8OutLength=ucasemap_utf8FoldCase(csm.getAlias(),
                    utf8Out, (int32_t)sizeof(utf8Out),
                    utf8In, utf8InLength, errorCode);
        break;
    default:
        name="";
        utf8OutLength=0;
        break; // won't happen
    }
    buffer=result.getBuffer(utf8OutLength);
    u_strFromUTF8(buffer, result.getCapacity(), &resultLength, utf8Out, utf8OutLength, errorCode);
    result.releaseBuffer(errorCode.isSuccess() ? resultLength : 0);

    if(errorCode.isFailure()) {
        errcheckln(errorCode, "error: %s() got an error for a test case from casing.res - %s", name, u_errorName(errorCode));
        errorCode.reset();
    } else if(result!=output) {
        errln("error: %s() got a wrong result for a test case from casing.res", name);
        errln("expected \"" + output + "\" got \"" + result + "\"" );
    }
}
void
StringCaseTest::TestCasingImpl(const UnicodeString &input,
                               const UnicodeString &output,
                               int32_t whichCase,
                               void *iter, const char *localeID, uint32_t options) {
    // UnicodeString
    UnicodeString result;
    const char *name;
    Locale locale(localeID);

    result=input;
    switch(whichCase) {
    case TEST_LOWER:
        name="toLower";
        result.toLower(locale);
        break;
    case TEST_UPPER:
        name="toUpper";
        result.toUpper(locale);
        break;
#if !UCONFIG_NO_BREAK_ITERATION
    case TEST_TITLE:
        name="toTitle";
        result.toTitle((BreakIterator *)iter, locale, options);
        break;
#endif
    case TEST_FOLD:
        name="foldCase";
        result.foldCase(options);
        break;
    default:
        name="";
        break; // won't happen
    }
    if(result!=output) {
        errln("error: UnicodeString.%s() got a wrong result for a test case from casing.res", name);
    }
#if !UCONFIG_NO_BREAK_ITERATION
    if(whichCase==TEST_TITLE && options==0) {
        result=input;
        result.toTitle((BreakIterator *)iter, locale);
        if(result!=output) {
            errln("error: UnicodeString.toTitle(options=0) got a wrong result for a test case from casing.res");
        }
    }
#endif

    // UTF-8
    char utf8In[100], utf8Out[100];
    int32_t utf8InLength, utf8OutLength, resultLength;
    UChar *buffer;

    UCaseMap *csm;
    UErrorCode errorCode;

    errorCode=U_ZERO_ERROR;
    csm=ucasemap_open(localeID, options, &errorCode);
#if !UCONFIG_NO_BREAK_ITERATION
    if(iter!=NULL) {
        // Clone the break iterator so that the UCaseMap can safely adopt it.
        int32_t size=1;  // Not 0 because that only gives preflighting.
        UBreakIterator *clone=ubrk_safeClone((UBreakIterator *)iter, NULL, &size, &errorCode);
        ucasemap_setBreakIterator(csm, clone, &errorCode);
    }
#endif

    u_strToUTF8(utf8In, (int32_t)sizeof(utf8In), &utf8InLength, input.getBuffer(), input.length(), &errorCode);
    switch(whichCase) {
    case TEST_LOWER:
        name="ucasemap_utf8ToLower";
        utf8OutLength=ucasemap_utf8ToLower(csm,
                    utf8Out, (int32_t)sizeof(utf8Out),
                    utf8In, utf8InLength, &errorCode);
        break;
    case TEST_UPPER:
        name="ucasemap_utf8ToUpper";
        utf8OutLength=ucasemap_utf8ToUpper(csm,
                    utf8Out, (int32_t)sizeof(utf8Out),
                    utf8In, utf8InLength, &errorCode);
        break;
#if !UCONFIG_NO_BREAK_ITERATION
    case TEST_TITLE:
        name="ucasemap_utf8ToTitle";
        utf8OutLength=ucasemap_utf8ToTitle(csm,
                    utf8Out, (int32_t)sizeof(utf8Out),
                    utf8In, utf8InLength, &errorCode);
        break;
#endif
    case TEST_FOLD:
        name="ucasemap_utf8FoldCase";
        utf8OutLength=ucasemap_utf8FoldCase(csm,
                    utf8Out, (int32_t)sizeof(utf8Out),
                    utf8In, utf8InLength, &errorCode);
        break;
    default:
        name="";
        utf8OutLength=0;
        break; // won't happen
    }
    buffer=result.getBuffer(utf8OutLength);
    u_strFromUTF8(buffer, result.getCapacity(), &resultLength, utf8Out, utf8OutLength, &errorCode);
    result.releaseBuffer(U_SUCCESS(errorCode) ? resultLength : 0);

    if(U_FAILURE(errorCode)) {
        errln("error: %s() got an error for a test case from casing.res - %s", name, u_errorName(errorCode));
    } else if(result!=output) {
        errln("error: %s() got a wrong result for a test case from casing.res", name);
    }
    ucasemap_close(csm);
}
Ejemplo n.º 4
0
UnicodeString& RelativeDateFormat::format(  Calendar& cal,
                                UnicodeString& appendTo,
                                FieldPosition& pos) const {

    UErrorCode status = U_ZERO_ERROR;
    UnicodeString relativeDayString;
    UDisplayContext capitalizationContext = getContext(UDISPCTX_TYPE_CAPITALIZATION, status);

    // calculate the difference, in days, between 'cal' and now.
    int dayDiff = dayDifference(cal, status);

    // look up string
    int32_t len = 0;
    const UChar *theString = getStringForDay(dayDiff, len, status);
    if(U_SUCCESS(status) && (theString!=NULL)) {
        // found a relative string
        relativeDayString.setTo(theString, len);
    }

    if ( relativeDayString.length() > 0 && !fDatePattern.isEmpty() &&
         (fTimePattern.isEmpty() || fCombinedFormat == NULL || fCombinedHasDateAtStart)) {
#if !UCONFIG_NO_BREAK_ITERATION
        // capitalize relativeDayString according to context for relative, set formatter no context
        if ( u_islower(relativeDayString.char32At(0)) && fCapitalizationBrkIter!= NULL &&
             ( capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE ||
               (capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU && fCapitalizationOfRelativeUnitsForUIListMenu) ||
               (capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_STANDALONE && fCapitalizationOfRelativeUnitsForStandAlone) ) ) {
            // titlecase first word of relativeDayString
            relativeDayString.toTitle(fCapitalizationBrkIter, fLocale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
        }
#endif
        fDateTimeFormatter->setContext(UDISPCTX_CAPITALIZATION_NONE, status);
    } else {
        // set our context for the formatter
        fDateTimeFormatter->setContext(capitalizationContext, status);
    }

    if (fDatePattern.isEmpty()) {
        fDateTimeFormatter->applyPattern(fTimePattern);
        fDateTimeFormatter->format(cal,appendTo,pos);
    } else if (fTimePattern.isEmpty() || fCombinedFormat == NULL) {
        if (relativeDayString.length() > 0) {
            appendTo.append(relativeDayString);
        } else {
            fDateTimeFormatter->applyPattern(fDatePattern);
            fDateTimeFormatter->format(cal,appendTo,pos);
        }
    } else {
        UnicodeString datePattern;
        if (relativeDayString.length() > 0) {
            // Need to quote the relativeDayString to make it a legal date pattern
            relativeDayString.findAndReplace(UNICODE_STRING("'", 1), UNICODE_STRING("''", 2)); // double any existing APOSTROPHE
            relativeDayString.insert(0, APOSTROPHE); // add APOSTROPHE at beginning...
            relativeDayString.append(APOSTROPHE); // and at end
            datePattern.setTo(relativeDayString);
        } else {
            datePattern.setTo(fDatePattern);
        }
        UnicodeString combinedPattern;
        fCombinedFormat->format(fTimePattern, datePattern, combinedPattern, status);
        fDateTimeFormatter->applyPattern(combinedPattern);
        fDateTimeFormatter->format(cal,appendTo,pos);
    }

    return appendTo;
}
Ejemplo n.º 5
0
void grid_renderer<T>::process(text_symbolizer const& sym,
                              Feature const& feature,
                              proj_transform const& prj_trans)
{
    typedef  coord_transform2<CoordTransform,geometry_type> path_type;

    bool placement_found = false;
    text_placement_info_ptr placement_options = sym.get_placement_options()->get_placement_info();
    while (!placement_found && placement_options->next())
    {
        expression_ptr name_expr = sym.get_name();
        if (!name_expr) return;
        value_type result = boost::apply_visitor(evaluate<Feature,value_type>(feature),*name_expr);
        UnicodeString text = result.to_unicode();

        if ( sym.get_text_transform() == UPPERCASE)
        {
            text = text.toUpper();
        }
        else if ( sym.get_text_transform() == LOWERCASE)
        {
            text = text.toLower();
        }
        else if ( sym.get_text_transform() == CAPITALIZE)
        {
            text = text.toTitle(NULL);
        }

        if ( text.length() <= 0 ) continue;
        color const& fill = sym.get_fill();

        face_set_ptr faces;

        if (sym.get_fontset().size() > 0)
        {
            faces = font_manager_.get_face_set(sym.get_fontset());
        }
        else
        {
            faces = font_manager_.get_face_set(sym.get_face_name());
        }

        stroker_ptr strk = font_manager_.get_stroker();
        if (!(faces->size() > 0 && strk))
        {
            throw config_error("Unable to find specified font face '" + sym.get_face_name() + "'");
        }
        text_renderer<T> ren(pixmap_, faces, *strk);
        ren.set_pixel_size(placement_options->text_size * (scale_factor_ * (1.0/pixmap_.get_resolution())));
        ren.set_fill(fill);
        ren.set_halo_fill(sym.get_halo_fill());
        ren.set_halo_radius(sym.get_halo_radius() * scale_factor_);
        ren.set_opacity(sym.get_text_opacity());

        // /pixmap_.get_resolution() ?
        box2d<double> dims(0,0,width_,height_);
        placement_finder<label_collision_detector4> finder(detector_,dims);

        string_info info(text);

        faces->get_string_info(info);
        unsigned num_geom = feature.num_geometries();
        for (unsigned i=0; i<num_geom; ++i)
        {
            geometry_type const& geom = feature.get_geometry(i);
            if (geom.num_points() == 0) continue; // don't bother with empty geometries
            while (!placement_found && placement_options->next_position_only())
            {
                placement text_placement(info, sym, scale_factor_);
                text_placement.avoid_edges = sym.get_avoid_edges();
                if (sym.get_label_placement() == POINT_PLACEMENT ||
                        sym.get_label_placement() == INTERIOR_PLACEMENT)
                {
                    double label_x, label_y, z=0.0;
                    if (sym.get_label_placement() == POINT_PLACEMENT)
                        geom.label_position(&label_x, &label_y);
                    else
                        geom.label_interior_position(&label_x, &label_y);
                    prj_trans.backward(label_x,label_y, z);
                    t_.forward(&label_x,&label_y);

                    double angle = 0.0;
                    expression_ptr angle_expr = sym.get_orientation();
                    if (angle_expr)
                    {
                        // apply rotation
                        value_type result = boost::apply_visitor(evaluate<Feature,value_type>(feature),*angle_expr);
                        angle = result.to_double();
                    }

                    finder.find_point_placement(text_placement, placement_options,
                                                label_x, label_y,
                                                angle, sym.get_line_spacing(),
                                                sym.get_character_spacing());

                    finder.update_detector(text_placement);
                }
                else if ( geom.num_points() > 1 && sym.get_label_placement() == LINE_PLACEMENT)
                {
                    path_type path(t_,geom,prj_trans);
                    finder.find_line_placements<path_type>(text_placement, placement_options, path);
                }

                if (!text_placement.placements.size()) continue;
                placement_found = true;

                for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ii)
                {
                    double x = text_placement.placements[ii].starting_x;
                    double y = text_placement.placements[ii].starting_y;
                    ren.prepare_glyphs(&text_placement.placements[ii]);
                    ren.render_id(feature.id(),x,y,2);
                }
            }
        }
    }
    if (placement_found)
        pixmap_.add_feature(feature);
}
Ejemplo n.º 6
0
QVariant
EnabledLocalesModel::data( const QModelIndex& index, int role ) const
{
    if ( index.row() < 0 || index.row() >= m_locales.count() )
        return QVariant();
    const QString& localeCode = m_locales[index.row()];

    Locale locale( localeCode.toLatin1() );

    // Get language and country in current system locale
    UnicodeString uDisplayLanguage;
    UnicodeString uDisplayCountry;
    locale.getDisplayLanguage( locale, uDisplayLanguage );
    locale.getDisplayCountry( locale, uDisplayCountry );

    // Capitalize language and country
    UErrorCode status;
    BreakIterator* titleIterator = BreakIterator::createTitleInstance( locale, status );
    uDisplayLanguage = uDisplayLanguage.toTitle( titleIterator );
    uDisplayCountry = uDisplayCountry.toTitle( titleIterator );

    QString displayLanguage = unicodeStringToQString( uDisplayLanguage );
    QString displayCountry = unicodeStringToQString( uDisplayCountry );

    switch ( role )
    {
    case Qt::DisplayRole:
        return QString( "%1 - %2 (%3)" ).arg( displayLanguage ).arg( displayCountry ).arg( localeCode );
    case LocaleCodeRole:
        return localeCode;
    case CountryRole:
        return displayCountry;
    case LanguageRole:
        return displayLanguage;
    case AddressRole:
        return address();
    case CollateRole:
        return collate();
    case CtypeRole:
        return ctype();
    case IdentificationRole:
        return identification();
    case LangRole:
        return lang();
    case LanguageLcRole:
        return language();
    case MeasurementRole:
        return measurement();
    case MonetaryRole:
        return monetary();
    case MessagesRole:
        return messages();
    case NameRole:
        return name();
    case NumericRole:
        return numeric();
    case PaperRole:
        return paper();
    case TelephoneRole:
        return telephone();
    case TimeRole:
        return time();
    }

    return QVariant();
}
void  agg_renderer<T>::process(shield_symbolizer const& sym,
                               Feature const& feature,
                               proj_transform const& prj_trans)
{
    typedef  coord_transform2<CoordTransform,geometry_type> path_type;


    text_placement_info_ptr placement_options = sym.get_placement_options()->get_placement_info();
    placement_options->next();
    placement_options->next_position_only();

    UnicodeString text;
    if( sym.get_no_text() )
        text = UnicodeString( " " );  // TODO: fix->use 'space' as the text to render
    else
    {
        expression_ptr name_expr = sym.get_name();
        if (!name_expr) return;
        value_type result = boost::apply_visitor(evaluate<Feature,value_type>(feature),*name_expr);
        text = result.to_unicode();
    }
    
    if ( sym.get_text_transform() == UPPERCASE)
    {
        text = text.toUpper();
    }
    else if ( sym.get_text_transform() == LOWERCASE)
    {
        text = text.toLower();
    }
    else if ( sym.get_text_transform() == CAPITALIZE)
    {
        text = text.toTitle(NULL);
    }
    
    agg::trans_affine tr;
    boost::array<double,6> const& m = sym.get_transform();
    tr.load_from(&m[0]);
    
    std::string filename = path_processor_type::evaluate( *sym.get_filename(), feature);
    boost::optional<mapnik::marker_ptr> marker;
    if ( !filename.empty() )
    {
        marker = marker_cache::instance()->find(filename, true);
    }
    else
    {
        marker.reset(boost::make_shared<mapnik::marker>());
    }
    
    
    if (text.length() > 0 && marker)
    {
        int w = (*marker)->width();
        int h = (*marker)->height();
        
        double px0 = - 0.5 * w;
        double py0 = - 0.5 * h;
        double px1 = 0.5 * w;
        double py1 = 0.5 * h;
        double px2 = px1;
        double py2 = py0;
        double px3 = px0;
        double py3 = py1;
        tr.transform(&px0,&py0);
        tr.transform(&px1,&py1);
        tr.transform(&px2,&py2);
        tr.transform(&px3,&py3);
        box2d<double> label_ext (px0, py0, px1, py1);
        label_ext.expand_to_include(px2, py2);
        label_ext.expand_to_include(px3, py3);
        
        face_set_ptr faces;

        if (sym.get_fontset().size() > 0)
        {
            faces = font_manager_.get_face_set(sym.get_fontset());
        }
        else
        {
            faces = font_manager_.get_face_set(sym.get_face_name());
        }

        stroker_ptr strk = font_manager_.get_stroker();
        if (strk && faces->size() > 0)
        {
            text_renderer<T> ren(pixmap_, faces, *strk);

            ren.set_pixel_size(sym.get_text_size() * scale_factor_);
            ren.set_fill(sym.get_fill());
            ren.set_halo_fill(sym.get_halo_fill());
            ren.set_halo_radius(sym.get_halo_radius() * scale_factor_);
            ren.set_opacity(sym.get_text_opacity());

            placement_finder<label_collision_detector4> finder(detector_);

            string_info info(text);

            faces->get_string_info(info);

            metawriter_with_properties writer = sym.get_metawriter();

            for (unsigned i = 0; i < feature.num_geometries(); ++i)
            {
                geometry_type const& geom = feature.get_geometry(i);
                if (geom.num_points() > 0 )
                {
                    path_type path(t_,geom,prj_trans);

                    label_placement_enum how_placed = sym.get_label_placement();
                    if (how_placed == POINT_PLACEMENT || how_placed == VERTEX_PLACEMENT || how_placed == INTERIOR_PLACEMENT)
                    {
                        // for every vertex, try and place a shield/text
                        geom.rewind(0);
                        placement text_placement(info, sym, scale_factor_, w, h, false);
                        text_placement.avoid_edges = sym.get_avoid_edges();
                        text_placement.allow_overlap = sym.get_allow_overlap();
                        if (writer.first)
                            text_placement.collect_extents =true; // needed for inmem metawriter
                        position const& pos = sym.get_displacement();
                        position const& shield_pos = sym.get_shield_displacement();
                        for( unsigned jj = 0; jj < geom.num_points(); jj++ )
                        {
                            double label_x;
                            double label_y;
                            double z=0.0;

                            if( how_placed == VERTEX_PLACEMENT )
                                geom.vertex(&label_x,&label_y);  // by vertex
                            else if( how_placed == INTERIOR_PLACEMENT )
                                geom.label_interior_position(&label_x,&label_y);
                            else
                                geom.label_position(&label_x, &label_y);  // by middle of line or by point
                            prj_trans.backward(label_x,label_y, z);
                            t_.forward(&label_x,&label_y);

                            label_x += boost::get<0>(shield_pos);
                            label_y += boost::get<1>(shield_pos);

                            finder.find_point_placement( text_placement, placement_options,
                                                         label_x, label_y, 0.0,
                                                         sym.get_line_spacing(),
                                                         sym.get_character_spacing());

                            // check to see if image overlaps anything too, there is only ever 1 placement found for points and verticies
                            if( text_placement.placements.size() > 0)
                            {
                                double x = floor(text_placement.placements[0].starting_x);
                                double y = floor(text_placement.placements[0].starting_y);
                                int px;
                                int py;
                                
                                if( !sym.get_unlock_image() )
                                {
                                    // center image at text center position
                                    // remove displacement from image label
                                    double lx = x - boost::get<0>(pos);
                                    double ly = y - boost::get<1>(pos);
                                    px=int(floor(lx - (0.5 * w))) + 1;
                                    py=int(floor(ly - (0.5 * h))) + 1;
                                    label_ext.re_center(lx,ly);
                                }
                                else
                                {  // center image at reference location
                                    px=int(floor(label_x - 0.5 * w));
                                    py=int(floor(label_y - 0.5 * h));
                                    label_ext.re_center(label_x,label_y);
                                }
                                
                                if ( sym.get_allow_overlap() || detector_.has_placement(label_ext) )
                                {
                                    render_marker(px,py,**marker,tr,sym.get_opacity());

                                    box2d<double> dim = ren.prepare_glyphs(&text_placement.placements[0]);
                                    ren.render(x,y);
                                    detector_.insert(label_ext);
                                    finder.update_detector(text_placement);
                                    if (writer.first) {
                                        writer.first->add_box(label_ext, feature, t_, writer.second);
                                        writer.first->add_text(text_placement, faces, feature, t_, writer.second);
                                    }
                                }
                            }
                        }
                    }

                    else if (geom.num_points() > 1 && how_placed == LINE_PLACEMENT)
                    {
                        placement text_placement(info, sym, scale_factor_, w, h, false);
                        position const& pos = sym.get_displacement();

                        text_placement.avoid_edges = sym.get_avoid_edges();
                        text_placement.additional_boxes.push_back(
                           box2d<double>(-0.5 * label_ext.width() - boost::get<0>(pos),
                                         -0.5 * label_ext.height() - boost::get<1>(pos),
                                         0.5 * label_ext.width() - boost::get<0>(pos),
                                         0.5 * label_ext.height() - boost::get<1>(pos)));
                        finder.find_point_placements<path_type>(text_placement, placement_options, path);

                        for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii)
                        {
                            double x = floor(text_placement.placements[ii].starting_x);
                            double y = floor(text_placement.placements[ii].starting_y);

                            double lx = x - boost::get<0>(pos);
                            double ly = y - boost::get<1>(pos);
                            int px=int(floor(lx - (0.5*w))) + 1;
                            int py=int(floor(ly - (0.5*h))) + 1;
                            label_ext.re_center(lx, ly);

                            render_marker(px,py,**marker,tr,sym.get_opacity());

                            box2d<double> dim = ren.prepare_glyphs(&text_placement.placements[ii]);
                            ren.render(x,y);
                            if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second);
                        }
                        finder.update_detector(text_placement);
                        if (writer.first) writer.first->add_text(text_placement, faces, feature, t_, writer.second);
                    }
                }
            }
        }
    }
}
void
SupportedLocalesModel::init( SupportedLocalesItem* parent )
{
    QStringList localeList { LanguageCommon::supportedLocales() };
    for ( const QString localeString : localeList )
    {
        Locale locale( localeString.toLatin1() );
        // Get language and country in current system locale
        UnicodeString uDisplayLanguage;
        UnicodeString uDisplayCountry;
        locale.getDisplayLanguage( locale, uDisplayLanguage );
        locale.getDisplayCountry( locale, uDisplayCountry );

        // Capitalize language and country
        UErrorCode status;
        BreakIterator* titleIterator = BreakIterator::createTitleInstance( locale, status );
        uDisplayLanguage = uDisplayLanguage.toTitle( titleIterator );
        uDisplayCountry = uDisplayCountry.toTitle( titleIterator );

        QString language = locale.getLanguage();
        QString country = locale.getCountry();
        QString displayLanguage = unicodeStringToQString( uDisplayLanguage );
        QString displayCountry = unicodeStringToQString( uDisplayCountry );

        // Search if we already added this language to the tree
        QModelIndexList languageIndexList = match( index( 0,0 ),
                                            KeyRole,
                                            language,
                                            -1,
                                            Qt::MatchFixedString );
        SupportedLocalesItem* languageItem;
        QModelIndex languageIndex;
        if ( languageIndexList.count() == 0 )
        {
            // Not found, add the language to the root
            languageItem = new SupportedLocalesItem( language, displayLanguage, parent );
            parent->appendChild( languageItem );
        }
        else
        {
            Q_ASSERT( languageIndexList.count() == 1 );
            // Found, convert index to a item
            languageIndex = languageIndexList.first();
            languageItem = static_cast<SupportedLocalesItem*>( languageIndex.internalPointer() );
        }

        // Search if we already added this country to this language
        QModelIndexList countryIndexList = match( languageIndex.child( 0,0 ),
                                           KeyRole,
                                           country,
                                           -1,
                                           Qt::MatchFixedString );
        SupportedLocalesItem* countryItem;
        QModelIndex countryIndex;
        if ( countryIndexList.count() == 0 )
        {
            // Not found, add the country to the language
            countryItem = new SupportedLocalesItem( country, displayCountry, languageItem );
            languageItem->appendChild( countryItem );
        }
        else
        {
            Q_ASSERT( countryIndexList.count() == 1 );
            // Found, convert index to a item
            countryIndex = countryIndexList.first();
            countryItem = static_cast<SupportedLocalesItem*>( countryIndex.internalPointer() );
        }

        // Add the locale code to the language
        SupportedLocalesItem* localeItem = new SupportedLocalesItem( localeString, localeString, countryItem );
        countryItem->appendChild( localeItem );
    }
}