22 QString currentNumber;
23 QList<QList<BlankSegments>> blankSegments;
24 constexpr char internalError[] =
"Internal error while processing blank segments";
26 auto appendLevel = [&blankSegments, &internalError](
int level ) ->
void
30 blankSegments.append( QList<BlankSegments>() );
32 else if ( level == 1 )
34 if ( blankSegments.isEmpty() )
35 throw std::runtime_error( internalError );
38 else if ( level == 2 )
40 if ( blankSegments.isEmpty() || blankSegments.back().isEmpty() )
41 throw std::runtime_error( internalError );
42 blankSegments.back().back().append( QPair<double, double>( -1, -1 ) );
45 throw std::runtime_error( internalError );
48 auto addNumber = [&blankSegments, &internalError, ¤tNumber](
const QChar &
c ) ->
void
50 if ( blankSegments.isEmpty() || blankSegments.back().isEmpty() || blankSegments.back().back().isEmpty() )
52 throw std::runtime_error( internalError );
55 if ( (
c ==
')' ||
c ==
',' ) && blankSegments.back().back().back().first == -1 )
57 throw std::runtime_error(
"Missing number" );
60 if ( blankSegments.back().back().back().second != -1 )
62 throw std::runtime_error(
"Too many number" );
66 const double number = currentNumber.toDouble( &ok );
69 throw std::runtime_error( QStringLiteral(
"bad formatted number '%1'" ).arg( currentNumber ).toStdString() );
73 if ( segments.back().first == -1 )
75 if ( segments.count() > 1 && segments.at( segments.count() - 2 ).second > number )
76 throw std::runtime_error( QStringLiteral(
"Wrong blank segments distances, start (%1) < previous end (%2)" ).arg( number ).arg( segments.at( segments.count() - 2 ).second ).toStdString() );
78 blankSegments.back().back().back().first = number;
80 else if ( blankSegments.back().back().back().first > number )
82 throw std::runtime_error( QStringLiteral(
"Wrong blank segments distances, start (%1) > end (%2)" ).arg( blankSegments.back().back().back().first ).arg( number ).toStdString() );
86 blankSegments.back().back().back().second = number;
88 currentNumber.clear();
95 for (
const QChar &
c : strBlankSegments )
97 if ( !currentNumber.isEmpty() && (
c.isSpace() ||
c ==
')' ||
c ==
',' ) )
100 throw std::runtime_error(
"Missing '('" );
107 throw std::runtime_error(
"Extraneous '('" );
108 appendLevel( ++level );
113 throw std::runtime_error(
"Extraneous ')'" );
114 if ( level == 2 && !blankSegments.isEmpty() && !blankSegments.back().isEmpty() && blankSegments.back().back().count() == 1
115 && blankSegments.back().back().back() == QPair<double, double>( -1, -1 ) )
117 blankSegments.back().back().pop_back();
124 if ( ( level == 0 && blankSegments.count() == 0 )
125 || ( level == 1 && !blankSegments.isEmpty() && blankSegments.back().count() == 0 )
126 || ( level == 2 && !blankSegments.isEmpty() && !blankSegments.back().isEmpty() && blankSegments.back().back().count() == 0 ) )
127 throw std::runtime_error(
"No elements, Not expecting ','" );
129 appendLevel( level );
131 else if (
c.isNumber() ||
c ==
'.' )
133 currentNumber.append(
c );
135 else if ( !
c.isSpace() )
137 throw std::runtime_error( QStringLiteral(
"Invalid character '%1'" ).arg(
c ).toStdString() );
143 throw std::runtime_error(
"Missing ')'" );
146 catch (
const std::exception &e )
148 blankSegments.clear();
149 error = QStringLiteral(
"%1 (column: %2)" ).arg( e.what() ).arg( iChar );
153 std::for_each( blankSegments.begin(), blankSegments.end(), [&renderContext, &unit]( QList<BlankSegments> &rings )
155 std::for_each( rings.begin(), rings.end(), [&renderContext, &unit]( BlankSegments & blankSegments )
157 std::for_each( blankSegments.begin(), blankSegments.end(), [&renderContext, &unit]( QPair<double, double> &blankSegment )
159 blankSegment.first = renderContext.convertToPainterUnits( blankSegment.first, unit );
160 blankSegment.second = renderContext.convertToPainterUnits( blankSegment.second, unit );
165 return blankSegments;
Contains information about the context of a rendering operation.