OSMAND_CORE_API QString OSMAND_CORE_CALL OsmAnd::ICU::convertToVisualOrder(const QString& input) { QString output; const auto len = input.length(); UErrorCode icuError = U_ZERO_ERROR; bool ok = true; // Allocate ICU BiDi context const auto pContext = ubidi_openSized(len, 0, &icuError); if(pContext == nullptr || !U_SUCCESS(icuError)) { LogPrintf(LogSeverityLevel::Error, "ICU error: %d", icuError); return input; } // Configure context to reorder from logical to visual ubidi_setReorderingMode(pContext, UBIDI_REORDER_DEFAULT); // Set data ubidi_setPara(pContext, reinterpret_cast<const UChar*>(input.unicode()), len, UBIDI_DEFAULT_RTL, nullptr, &icuError); ok = U_SUCCESS(icuError); if(ok) { QVector<UChar> reordered(len); ubidi_writeReordered(pContext, reordered.data(), len, UBIDI_DO_MIRRORING | UBIDI_REMOVE_BIDI_CONTROLS, &icuError); ok = U_SUCCESS(icuError); if(ok) { QVector<UChar> reshaped(len); const auto newLen = u_shapeArabic(reordered.constData(), len, reshaped.data(), len, U_SHAPE_TEXT_DIRECTION_VISUAL_LTR | U_SHAPE_LETTERS_SHAPE | U_SHAPE_LENGTH_FIXED_SPACES_AT_END, &icuError); ok = U_SUCCESS(icuError); if(ok) { output = qMove(QString(reinterpret_cast<const QChar*>(reshaped.constData()), newLen)); } } } // Release context ubidi_close(pContext); if(!ok) { LogPrintf(LogSeverityLevel::Error, "ICU error: %d", icuError); return input; } return output; }
void ipod_browse_photo_dialog::refresh_photo() { t_size count = m_library.artwork_object.image_list.get_count(); bool found = false; if (m_index < count && m_format < m_library.artwork_object.image_list[m_index].image_names.get_count()) { ipod_device_ptr_cref_t p_ipod = m_this->m_drive_scanner.m_ipods[0]; photodb::t_image_name & image = m_library.artwork_object.image_list[m_index].image_names[m_format]; artwork_format_t p_format; if (p_ipod->m_device_properties.get_artwork_format_by_id(image.correlation_id, p_format)) { //artwork_format_t const & p_format = p_ipod->m_device_properties.m_artwork_formats[artwork_format_index]; found = true; pfc::string8 temp = image.location; temp.replace_byte(':', p_ipod->get_path_separator()); pfc::string8 path; p_ipod->get_database_path(path); path << p_ipod->get_path_separator_ptr() << "Artwork" << temp; //path << "\\Photos" << temp; service_ptr_t<t_threaded_file_reader> callback = new service_impl_t< t_threaded_file_reader > (path, image.file_offset, image.file_size); ; if (threaded_process::g_run_modal(callback, threaded_process::flag_show_abort, core_api::get_main_window(), "Loading image...") && !callback->m_failed) { if (callback->m_data.get_size() == p_format.get_raw_size()) { const t_uint8 * p_data = callback->m_data.get_ptr(); bitmap_utils::bitmap_from_alternative_pixel_order_t reordered((t_uint16*)p_data, p_format.m_render_width, p_format.m_render_height, p_format.get_row_stride() / 2); if (p_format.m_alternate_pixel_order) { p_data = reordered.from_alternative_order(); } if (p_format.m_pixel_format == 'UYUV') m_viewer.set_bitmap(bitmap_utils::create_bitmap_from_uyvy(p_data, callback->m_data.get_size(), p_format.m_render_width, p_format.m_render_height)); else if (p_format.m_pixel_format == 'L565') m_viewer.set_bitmap(bitmap_utils::create_bitmap_from_rgb565(p_data, callback->m_data.get_size(), p_format.m_render_width, p_format.m_render_height, p_format.get_row_stride())); else if (p_format.m_pixel_format == 'L555') m_viewer.set_bitmap(bitmap_utils::create_bitmap_from_rgb565(p_data, callback->m_data.get_size(), p_format.m_render_width, p_format.m_render_height, p_format.get_row_stride(), true)); else if (p_format.m_pixel_format == 'jpeg') m_viewer.set_bitmap(bitmap_utils::create_bitmap_from_jpeg(p_data, callback->m_data.get_size(), p_format.m_render_width, p_format.m_render_height)); } RedrawWindow(m_viewer.get_wnd(), NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASE); } } } }
void sefield::TetMesh::axisOrderElements(uint opt_method, std::string const & opt_file_name) { // Now this method provides a choice between Stefan and Robert's method // and the new method by Iain. The original method is fast and suffices for // simple geometries, Iain's method is superior and important for complex // geometries, but slow. if (opt_file_name != "") { std::fstream opt_file; opt_file.open(opt_file_name.c_str(), std::fstream::in | std::fstream::binary); opt_file.seekg(0); uint nelems = 0; opt_file.read((char*)&nelems, sizeof(uint)); if (pElements.size() != nelems) { std::ostringstream os; os << "optimal data mismatch with simulator parameters: sefield::Tetmesh::nelems, "; os << nelems << ":" << pElements.size(); throw steps::ArgErr(os.str()); } opt_file.read((char*)pVertexPerm, sizeof(uint) * nelems); VertexElementPVec elements_temp = pElements; for (uint vidx = 0; vidx < nelems; ++vidx) { VertexElementP vep = elements_temp[vidx]; // sanity check assert(vep->getIDX() == vidx); uint new_idx = pVertexPerm[vidx]; pElements[new_idx] = vep; } reindexElements(); reordered(); opt_file.close(); return; } if (opt_method == 2) { // / / / / / / / / / / / / / / NEW / / / / / / / / / / / / / / / / / / // // LOOPING OVER ALL VERTICES, APPLYING THE WALK METHOD AND FINDING WHICH // STARTING VERTEX GIVES THE LOWEST MATRIX WIDTH. uint pNVerts = pElements.size(); // the best vertex(narrowest width) uint bestone = 0; uint bestwidth = pNVerts; std::vector<VertexElement*> orig_indices = pElements; stringstream ss; ss << "\nFinding optimal vertex indexing. This can take some time..."; cout << ss.str() << endl; for (uint vidx = 0; vidx < pNVerts; ++vidx) { set<VertexElement*> verteleset = set<VertexElement*>(); vector<VertexElement*> vertelevec = vector<VertexElement*>(); queue<VertexElement*> vertelqueue = queue<VertexElement*>(); verteleset.insert(orig_indices[vidx]); vertelevec.push_back(orig_indices[vidx]); uint ve0ncons = orig_indices[vidx]->getNCon(); VertexElement ** ve0neighbs = orig_indices[vidx]->getNeighbours(); fill_ve_vec(verteleset, vertelevec, vertelqueue, ve0ncons, ve0neighbs); pElements.clear(); vector<VertexElement*>::iterator vertele_end = vertelevec.end(); uint ielt = 0; for (vector<VertexElement*>::iterator vertele = vertelevec.begin(); vertele != vertele_end; ++vertele) { pElements.push_back(*vertele); pVertexPerm[(*vertele)->getIDX()]=ielt; ielt++; } // Note: this will reorder the vertex indices as we go- not a problem in this loop // but they must be reset for the final index setting to work reindexElements(); uint maxdi = 0; for (int iv = 0; iv < pNVerts; ++iv) { VertexElement* ve = getVertex(iv); int ind = ve->getIDX(); for (int i = 0; i < ve->getNCon(); ++i) { int inbr = ve->nbrIdx(i); int di = ind - inbr; if (di < 0) { di = -di; } if (di > maxdi) { maxdi = di; } } } if (maxdi < bestwidth) { bestone = vidx; bestwidth = maxdi; //cout << "\nOriginal vertex "<< vidx << " gives banded matrix half-width " << maxdi; } } // reset the vertex indices to their original value: important for (uint v = 0; v < pNVerts; ++v) { orig_indices[v]->setIDX(v); } set<VertexElement*> verteleset = set<VertexElement*>(); vector<VertexElement*> vertelevec = vector<VertexElement*>(); queue<VertexElement*> vertelqueue = queue<VertexElement*>(); verteleset.insert(orig_indices[bestone]); vertelevec.push_back(orig_indices[bestone]); uint ve0ncons = orig_indices[bestone]->getNCon(); VertexElement ** ve0neighbs = orig_indices[bestone]->getNeighbours(); fill_ve_vec(verteleset, vertelevec, vertelqueue, ve0ncons, ve0neighbs); pElements.clear(); vector<VertexElement*>::iterator vertele_end = vertelevec.end(); uint ielt = 0; for (vector<VertexElement*>::iterator vertele = vertelevec.begin(); vertele != vertele_end; ++vertele) { pElements.push_back(*vertele); pVertexPerm[(*vertele)->getIDX()]=ielt; ielt++; } } // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / // else if (opt_method == 1) { /* THIS ORIGINAL CODE REPLACED WITH NEW 'WALKING' METHOD. A DRAMATIC REDUCTION IN BAND HALF-WIDTHS FOR COMPLEX 3D MESHES. This is not the end of the story: TODO investigate whether reordering a vertices neighbour's for the queue by distance will improve again. */ std::vector<double> com = centerOfMass(); double ** m = new double*[3]; for (uint i = 0; i < 3; i++) { m[i] = new double[3]; m[i][0] = 0.0; m[i][1] = 0.0; m[i][2] = 0.0; } for (uint ivert = 0; ivert < countVertices(); ivert++) { VertexElement* ve = getVertex(ivert); double x = ve->getX() - com[0]; double y = ve->getY() - com[1]; double z = ve->getZ() - com[2]; m[0][0] += x * x; m[0][1] += x * y; m[0][2] += x * z; m[1][0] += y * x; m[1][1] += y * y; m[1][2] += y * z; m[2][0] += z * x; m[2][1] += z * y; m[2][2] += z * z; } uint iret; double gamma; double evec[3]; mainEvec(3, m, &iret, &gamma, evec); if (iret != 1) { cout << "\nWarning - eigenvalue faliure " << endl; } for (uint i = 0; i < 3; i++) { delete[] m[i]; } delete[] m; double vx = evec[0]; double vy = evec[1]; double vz = evec[2]; vx += 1.e-8; vy += 1.e-9; vz += 1.e-10; stringstream ss; ss << "aligning to axis " << vx << " " << vy << " " << vz << endl; //cout << ss.str(); map<double, VertexElement*> hm; //vector<double> da; for (uint ielt = 0; ielt < countVertices(); ielt++) { VertexElement * ve = getVertex(ielt); double d = vx * ve->getX() + vy * ve->getY() + vz * ve->getZ(); hm[d] = ve; //da.push_back(d); } //sort(da.begin(), da.end()); pElements.clear(); uint ielt = 0; map<double, VertexElement*>::const_iterator iter = hm.begin(); while (iter != hm.end()) { double d = iter->first; pElements.push_back(hm[d]); ++iter; // pVertexPerm[i] contains the new index in the elements array // for the vertex that was originally at index i pVertexPerm[hm[d]->getIDX()] = ielt; ielt++; } } else { std::ostringstream os; os << "Unknown optimization method.\n"; throw steps::ArgErr(os.str()); } reindexElements(); reordered(); }