float StraightPath::advance(const glm::vec3 & pos, const float dist) const { if (!isOnPath(pos)) { LOG_WARNING("pos not on path"); return -1.f; } const auto newPos = pos + dist * glm::normalize(m_b - m_a); return glm::length(newPos - m_a) / glm::length(m_b - m_a); }
QVector<QPointF> ArtisticTextShape::calculateAbstractCharacterPositions() { const int totalTextLength = plainText().length(); QVector<QPointF> charPositions; // one more than the number of characters for position after the last character charPositions.resize(totalTextLength+1); // the character index within the text shape int globalCharIndex = 0; QPointF charPos(0, 0); QPointF advance(0, 0); const bool attachedToPath = isOnPath(); foreach(const ArtisticTextRange &range, m_ranges) { QFontMetricsF metrics(QFont(range.font(), &m_paintDevice)); const QString textRange = range.text(); const qreal letterSpacing = range.letterSpacing(); const int localTextLength = textRange.length(); const bool absoluteXOffset = range.xOffsetType() == ArtisticTextRange::AbsoluteOffset; const bool absoluteYOffset = range.yOffsetType() == ArtisticTextRange::AbsoluteOffset; // set baseline shift const qreal baselineShift = baselineShiftForFontSize(range, defaultFont().pointSizeF()); for(int localCharIndex = 0; localCharIndex < localTextLength; ++localCharIndex, ++globalCharIndex) { // apply offset to character if (range.hasXOffset(localCharIndex)) { if (absoluteXOffset) charPos.rx() = range.xOffset(localCharIndex); else charPos.rx() += range.xOffset(localCharIndex); } else { charPos.rx() += advance.x(); } if (range.hasYOffset(localCharIndex)) { if (absoluteYOffset) { // when attached to a path, absolute y-offsets are ignored if (!attachedToPath) charPos.ry() = range.yOffset(localCharIndex); } else { charPos.ry() += range.yOffset(localCharIndex); } } else { charPos.ry() += advance.y(); } // apply baseline shift charPos.ry() += baselineShift; // save character position of current character charPositions[globalCharIndex] = charPos; // advance character position advance = QPointF(metrics.width(textRange[localCharIndex])+letterSpacing, 0.0); charPos.ry() -= baselineShift; } }