| 2509 | |
| 2510 | template< class Format > |
| 2511 | void OcdFileExport::exportPathObject(OcdFile<Format>& file, const PathObject* path, bool lines_only) |
| 2512 | { |
| 2513 | typename Format::Object ocd_object = {}; |
| 2514 | typename Format::Object::IndexEntryType entry = {}; |
| 2515 | |
| 2516 | bool need_split_lines = false; |
| 2517 | auto symbol = path->getSymbol(); |
| 2518 | if (symbol && symbol->getContainedTypes() & Symbol::Area) |
| 2519 | { |
| 2520 | ocd_object.type = 3; // Area symbol |
| 2521 | // We we may get away with an object with holes, |
| 2522 | // but need to check the breakdown. |
| 2523 | if (symbol->getType() == Symbol::Area) |
| 2524 | { |
| 2525 | if (static_cast<const AreaSymbol*>(symbol)->hasRotatableFillPattern()) |
| 2526 | ocd_object.angle = decltype(ocd_object.angle)(convertRotation(path->getPatternRotation())); |
| 2527 | if (path->getPatternOrigin() != MapCoord(0, 0)) |
| 2528 | addWarning(::OpenOrienteering::OcdFileExport::tr("Unable to export fill pattern shift for an area object")); |
| 2529 | } |
| 2530 | } |
| 2531 | else |
| 2532 | { |
| 2533 | ocd_object.type = 2; // Line symbol |
| 2534 | // We need to split multiple path parts into multiple Ocd objects. |
| 2535 | need_split_lines = path->parts().size() > 1; |
| 2536 | } |
| 2537 | |
| 2538 | if (!need_split_lines) |
| 2539 | { |
| 2540 | ocd_object.symbol = entry.symbol = decltype(entry.symbol)(symbol_numbers[symbol]); |
| 2541 | auto data = exportObjectCommon(path, ocd_object, entry); |
| 2542 | FILEFORMAT_ASSERT(!data.isEmpty()); |
| 2543 | |
| 2544 | auto breakdown_index_entry = breakdown_index.find(quint32(entry.symbol)); |
| 2545 | if (breakdown_index_entry == end(breakdown_index)) |
| 2546 | { |
| 2547 | // Regular symbol which does not need to be split |
| 2548 | file.objects().insert(data, entry); |
| 2549 | return; |
| 2550 | } |
| 2551 | |
| 2552 | // Combined symbol |
| 2553 | auto backlog = std::vector<quint32>(); |
| 2554 | auto offset = quint32(breakdown_index_entry->second); |
| 2555 | auto& exported_ocd_object = reinterpret_cast<typename Format::Object&>(*data.data()); |
| 2556 | do |
| 2557 | { |
| 2558 | auto breakdown = begin(breakdown_list) + offset; |
| 2559 | for ( ; breakdown->number != 0; ++breakdown) |
| 2560 | { |
| 2561 | if (Q_UNLIKELY(breakdown->type == 99)) |
| 2562 | { |
| 2563 | auto child_index_entry = breakdown_index.find(breakdown->number); |
| 2564 | FILEFORMAT_ASSERT(child_index_entry != end(breakdown_index)); |
| 2565 | backlog.push_back(quint32(child_index_entry->second)); |
| 2566 | continue; |
| 2567 | } |
| 2568 | if (breakdown->type != 2 && lines_only) |
nothing calls this directly
no test coverage detected