diff --git a/ui/pagepainter.h b/ui/pagepainter.h --- a/ui/pagepainter.h +++ b/ui/pagepainter.h @@ -92,6 +92,7 @@ private: void drawMainLine( QImage &image ) const; + void drawCaption( QImage &image, double mainSegmentLength, double angle ) const; void drawShortenedLine( double mainSegmentLength, double size, QImage &image, const QTransform& constructionMatrix ) const; void drawLineEnds( double mainSegmentLength, double size, QImage &image, const QTransform& transform ) const; void drawLineEndArrow( double xEndPos, double size, double flipX, bool close, const QTransform& constructionMatrix, QImage &image ) const; diff --git a/ui/pagepainter.cpp b/ui/pagepainter.cpp --- a/ui/pagepainter.cpp +++ b/ui/pagepainter.cpp @@ -989,22 +989,26 @@ void LineAnnotPainter::draw( QImage &image ) const { + const Okular::NormalizedPoint delta { + la->transformedLinePoints().last().x - la->transformedLinePoints().first().x, + la->transformedLinePoints().first().y - la->transformedLinePoints().last().y + }; + const double deaspectedY { delta.y * aspectRatio }; + const double angle { atan2( delta.y * aspectRatio, delta.x ) }; + const double mainSegmentLength { sqrt( delta.x * delta.x + deaspectedY * deaspectedY ) }; + + if ( la->showCaption() ) + drawCaption( image, mainSegmentLength, angle ); + if ( la->transformedLinePoints().count() == 2 ) { - const Okular::NormalizedPoint delta { - la->transformedLinePoints().last().x - la->transformedLinePoints().first().x, - la->transformedLinePoints().first().y - la->transformedLinePoints().last().y - }; - const double angle { atan2( delta.y * aspectRatio, delta.x ) }; const double cosA { cos( -angle ) }; const double sinA { sin( -angle ) }; const QTransform tmpMatrix = QTransform { cosA, sinA / aspectRatio, -sinA, cosA / aspectRatio, la->transformedLinePoints().first().x, la->transformedLinePoints().first().y }; - const double deaspectedY { delta.y * aspectRatio }; - const double mainSegmentLength { sqrt( delta.x * delta.x + deaspectedY * deaspectedY ) }; const double lineendSize { std::min( 6. * la->style().width() / pageSize.width(), mainSegmentLength / 2. ) }; drawShortenedLine( mainSegmentLength, lineendSize, image, tmpMatrix ); @@ -1026,6 +1030,38 @@ linePen, fillBrush, pageScale, PagePainter::Multiply ); } +void LineAnnotPainter::drawCaption( QImage &image, double mainSegmentLength, double angle ) const +{ + QPainter painter( &image ); + QFont captionFont; + const QFontMetrics captionFontMetrics { captionFont }; + const double textHeight = static_cast( captionFontMetrics.height() ); + const int flags = Qt::AlignHCenter | Qt::AlignBottom | Qt::TextDontClip; + painter.setFont( captionFont ); + painter.setRenderHint( QPainter::TextAntialiasing ); + + /* + * The only sane way to draw arbitrary rotated text is using QPainter::rotate. + * But that doesn't work with normalized coordinates, + * because we can't scale the font size reliably to something in 0..1. + * So we denormalize our local construction coordinate system prior to using drawText. + */ + const QRectF denormalizedRectangle { + QPointF { 0, -textHeight }, + QSizeF { mainSegmentLength * pageSize.width(), textHeight } + }; + + /* Then let QPainter do all further transformation. */ + painter.setTransform( + QTransform().rotate( -angle * 180. / M_PI ) * + QTransform::fromScale( 1. / pageSize.width(), 1. / pageSize.height() ) * + QTransform::fromTranslate( la->transformedLinePoints().first().x, la->transformedLinePoints().first().y ) * + paintMatrix * + QTransform::fromScale( image.width(), image.height() ) + ); + painter.drawText( denormalizedRectangle, flags, la->contents() ); +} + void LineAnnotPainter::drawShortenedLine( double mainSegmentLength, double size, QImage &image, const QTransform& constructionMatrix ) const { const QTransform combinedTransform { constructionMatrix * paintMatrix }; @@ -1226,4 +1262,3 @@ } /* kate: replace-tabs on; indent-width 4; */ -