Commit e44ff387 authored by Dileep Sankhla's avatar Dileep Sankhla Committed by Tobias Deiminger

Support setting text color for typewriter annotations

Summary:
Changing typewriter text color can be done in the typewriter properties dialog, or programmatically via new okular API methods TextAnnotation::textColor and TextAnnotation::setTextColor.

poppler >= 0.69 is required to store text color natively inside PDF documents. For other document types, text color is stored as metadata inside the document archive.

This work was done during GSoC 2018. See https://community.kde.org/GSoC/2018/StatusReports/DileepSankhla for details.

Test Plan:
- properties dialog of typewriter annotation has "Font Color" picker
- saving to PDF results in <r> <g> <b> rg operation in /DA
- saving to archive results in fontColor="rrggbb" attribute in metadata.xml

Reviewers: sander

Reviewed By: sander

Subscribers: kde-doc-english, sander, okular-devel

Tags: #okular, #documentation

Differential Revision: https://phabricator.kde.org/D15205
parent 3cdb348d
......@@ -133,6 +133,7 @@ QDomDocument EditAnnotToolDialog::toolXml() const
engineElement.appendChild( annotationElement );
const QString color = m_stubann->style().color().name( QColor::HexArgb );
const QString textColor = static_cast< Okular::TextAnnotation * >( m_stubann )->textColor().name();
const QString opacity = QString::number( m_stubann->style().opacity() );
const QString width = QString::number( m_stubann->style().width() );
......@@ -271,10 +272,10 @@ QDomDocument EditAnnotToolDialog::toolXml() const
Okular::TextAnnotation * ta = static_cast<Okular::TextAnnotation*>( m_stubann );
toolElement.setAttribute( QStringLiteral("type"), QStringLiteral("typewriter") );
engineElement.setAttribute( QStringLiteral("type"), QStringLiteral("PickPoint") );
engineElement.setAttribute( QStringLiteral("color"), color );
engineElement.setAttribute( QStringLiteral("block"), QStringLiteral("true") );
annotationElement.setAttribute( QStringLiteral("type"), QStringLiteral("Typewriter") );
annotationElement.setAttribute( QStringLiteral("color"), color );
annotationElement.setAttribute( QStringLiteral("textColor"), textColor );
annotationElement.setAttribute( QStringLiteral("width"), width );
if ( ta->textFont() != QApplication::font() )
annotationElement.setAttribute( QStringLiteral("font"), ta->textFont().toString() );
......@@ -362,6 +363,7 @@ void EditAnnotToolDialog::createStubAnnotation()
ta->setInplaceIntent( Okular::TextAnnotation::TypeWriter );
ta->style().setWidth( 0.0 );
ta->style().setColor( QColor(255,255,255,0) );
ta->setTextColor( Qt::black );
m_stubann = ta;
}
}
......@@ -504,6 +506,8 @@ void EditAnnotToolDialog::loadTool( const QDomElement &toolElement )
f.fromString( annotationElement.attribute( QStringLiteral("font") ) );
ta->setTextFont( f );
}
if ( annotationElement.hasAttribute( QStringLiteral("textColor") ) )
ta->setTextColor( QColor( annotationElement.attribute( QStringLiteral("textColor") ) ) );
}
// Common properties
......
......@@ -1028,6 +1028,7 @@ class Okular::TextAnnotationPrivate : public Okular::AnnotationPrivate
TextAnnotation::TextType m_textType;
QString m_textIcon;
QFont m_textFont;
QColor m_textColor;
int m_inplaceAlign;
NormalizedPoint m_inplaceCallout[3];
NormalizedPoint m_transformedInplaceCallout[3];
......@@ -1087,6 +1088,18 @@ QFont TextAnnotation::textFont() const
return d->m_textFont;
}
void TextAnnotation::setTextColor( const QColor &color )
{
Q_D( TextAnnotation );
d->m_textColor = color;
}
QColor TextAnnotation::textColor() const
{
Q_D( const TextAnnotation );
return d->m_textColor;
}
void TextAnnotation::setInplaceAlignment( int alignment )
{
Q_D( TextAnnotation );
......@@ -1160,6 +1173,8 @@ void TextAnnotation::store( QDomNode & node, QDomDocument & document ) const
textElement.setAttribute( QStringLiteral("icon"), d->m_textIcon );
if ( d->m_textFont != QApplication::font() )
textElement.setAttribute( QStringLiteral("font"), d->m_textFont.toString() );
if ( d->m_textColor.isValid() )
textElement.setAttribute( QStringLiteral("fontColor"), d->m_textColor.name() );
if ( d->m_inplaceAlign )
textElement.setAttribute( QStringLiteral("align"), d->m_inplaceAlign );
if ( d->m_inplaceIntent != Unknown )
......@@ -1246,6 +1261,8 @@ void TextAnnotationPrivate::setAnnotationProperties( const QDomNode& node )
m_textIcon = e.attribute( QStringLiteral("icon") );
if ( e.hasAttribute( QStringLiteral("font") ) )
m_textFont.fromString( e.attribute( QStringLiteral("font") ) );
if ( e.hasAttribute( QStringLiteral("fontColor") ) )
m_textColor = QColor( e.attribute( QStringLiteral("fontColor") ) );
if ( e.hasAttribute( QStringLiteral("align") ) )
m_inplaceAlign = e.attribute( QStringLiteral("align") ).toInt();
if ( e.hasAttribute( QStringLiteral("intent") ) )
......
......@@ -819,6 +819,20 @@ class OKULARCORE_EXPORT TextAnnotation : public Annotation
*/
QFont textFont() const;
/**
* Sets the @p color of inplace text.
*
* @since 1.6
*/
void setTextColor( const QColor &color );
/**
* Returns the color of inplace text.
*
* @since 1.6
*/
QColor textColor() const;
/**
* Sets the inplace @p alignment of the text annotation.
*/
......
......@@ -96,6 +96,17 @@ int main()
}
" HAVE_POPPLER_0_65)
check_cxx_source_compiles("
#include <poppler-qt5.h>
#include <QColor>
int main()
{
Poppler::TextAnnotation *annot = new Poppler::TextAnnotation( Poppler::TextAnnotation::InPlace );
annot->setTextColor( Qt::blue );
return 0;
}
" HAVE_POPPLER_0_69)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/config-okular-poppler.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/config-okular-poppler.h
......
......@@ -180,6 +180,9 @@ void PopplerAnnotationProxy::notifyModification( const Okular::Annotation *okl_a
Poppler::TextAnnotation * ppl_txtann = static_cast<Poppler::TextAnnotation*>(ppl_ann);
ppl_txtann->setTextIcon( okl_txtann->textIcon() );
ppl_txtann->setTextFont( okl_txtann->textFont() );
#ifdef HAVE_POPPLER_0_69
ppl_txtann->setTextColor( okl_txtann->textColor() );
#endif //HAVE_POPPLER_0_69
ppl_txtann->setInplaceAlign( okl_txtann->inplaceAlignment() );
ppl_txtann->setCalloutPoints( QVector<QPointF>() );
ppl_txtann->setInplaceIntent( (Poppler::TextAnnotation::InplaceIntent)okl_txtann->inplaceIntent() );
......
......@@ -30,3 +30,6 @@
/* Defined if we have the 0.65 version of the Poppler library */
#cmakedefine HAVE_POPPLER_0_65 1
/* Defined if we have the 0.69 version of the Poppler library */
#cmakedefine HAVE_POPPLER_0_69 1
......@@ -286,16 +286,24 @@ void TextAnnotationWidget::applyChanges()
AnnotationWidget::applyChanges();
if ( m_textAnn->textType() == Okular::TextAnnotation::Linked )
{
Q_ASSERT( m_pixmapSelector );
m_textAnn->setTextIcon( m_pixmapSelector->icon() );
}
else if ( m_textAnn->textType() == Okular::TextAnnotation::InPlace )
{
Q_ASSERT( m_fontReq );
m_textAnn->setTextFont( m_fontReq->font() );
if ( !isTypewriter() )
{
Q_ASSERT( m_textAlign && m_spinWidth );
m_textAnn->setInplaceAlignment( m_textAlign->currentIndex() );
m_textAnn->style().setWidth( m_spinWidth->value() );
}
else
{
Q_ASSERT( m_textColorBn );
m_textAnn->setTextColor( m_textColorBn->color() );
}
}
}
......@@ -310,15 +318,16 @@ void TextAnnotationWidget::createPopupNoteStyleUi( QWidget * widget, QVBoxLayout
void TextAnnotationWidget::createInlineNoteStyleUi( QWidget * widget, QVBoxLayout * layout ) {
QGridLayout * innerlay = new QGridLayout();
layout->addLayout( innerlay );
addFontRequester(widget, innerlay);
addTextAlignComboBox(widget, innerlay);
addWidthSpinBox(widget, innerlay);
addFontRequester( widget, innerlay );
addTextAlignComboBox( widget, innerlay );
addWidthSpinBox( widget, innerlay );
}
void TextAnnotationWidget::createTypewriterStyleUi( QWidget * widget, QVBoxLayout * layout ) {
QGridLayout * innerlay = new QGridLayout();
layout->addLayout( innerlay );
addFontRequester(widget, innerlay);
addFontRequester( widget, innerlay );
addTextColorButton( widget, innerlay );
}
void TextAnnotationWidget::addPixmapSelector( QWidget * widget, QLayout * layout )
......@@ -338,20 +347,34 @@ void TextAnnotationWidget::addPixmapSelector( QWidget * widget, QLayout * layout
void TextAnnotationWidget::addFontRequester( QWidget * widget, QGridLayout * layout )
{
const int row = layout->rowCount();
QLabel * tmplabel = new QLabel( i18n( "Font:" ), widget );
layout->addWidget( tmplabel, 0, 0 );
layout->addWidget( tmplabel, row, 0 );
m_fontReq = new KFontRequester( widget );
layout->addWidget( m_fontReq, 0, 1 );
layout->addWidget( m_fontReq, row, 1 );
m_fontReq->setFont( m_textAnn->textFont() );
connect( m_fontReq, &KFontRequester::fontSelected, this, &AnnotationWidget::dataChanged );
}
void TextAnnotationWidget::addTextColorButton( QWidget * widget, QGridLayout * layout )
{
const int row = layout->rowCount();
QLabel * tmplabel = new QLabel( i18n( "&Text Color:" ), widget );
layout->addWidget( tmplabel, row, 0, Qt::AlignRight );
m_textColorBn = new KColorButton( widget );
m_textColorBn->setColor( m_textAnn->textColor() );
tmplabel->setBuddy( m_textColorBn );
layout->addWidget( m_textColorBn, row, 1 );
connect( m_textColorBn, &KColorButton::changed, this, &AnnotationWidget::dataChanged );
}
void TextAnnotationWidget::addTextAlignComboBox( QWidget * widget, QGridLayout * layout )
{
const int row = layout->rowCount();
QLabel * tmplabel = new QLabel( i18n( "Align:" ), widget );
layout->addWidget( tmplabel, 1, 0 );
layout->addWidget( tmplabel, row, 0 );
m_textAlign = new KComboBox( widget );
layout->addWidget( m_textAlign, 1, 1 );
layout->addWidget( m_textAlign, row, 1 );
m_textAlign->addItem( i18n("Left") );
m_textAlign->addItem( i18n("Center") );
m_textAlign->addItem( i18n("Right") );
......@@ -361,10 +384,11 @@ void TextAnnotationWidget::addTextAlignComboBox( QWidget * widget, QGridLayout *
void TextAnnotationWidget::addWidthSpinBox( QWidget * widget, QGridLayout * layout )
{
const int row = layout->rowCount();
QLabel * tmplabel = new QLabel( i18n( "Border Width:" ), widget );
layout->addWidget( tmplabel, 2, 0, Qt::AlignRight );
layout->addWidget( tmplabel, row, 0, Qt::AlignRight );
m_spinWidth = new QDoubleSpinBox( widget );
layout->addWidget( m_spinWidth, 2, 1 );
layout->addWidget( m_spinWidth, row, 1 );
tmplabel->setBuddy( m_spinWidth );
m_spinWidth->setRange( 0, 100 );
m_spinWidth->setValue( m_textAnn->style().width() );
......
......@@ -127,6 +127,7 @@ private:
void createTypewriterStyleUi( QWidget * widget, QVBoxLayout * layout );
void addPixmapSelector( QWidget * widget, QLayout * layout );
void addFontRequester( QWidget * widget, QGridLayout * layout );
void addTextColorButton( QWidget * widget, QGridLayout * layout );
void addTextAlignComboBox( QWidget * widget, QGridLayout * layout );
void addWidthSpinBox( QWidget * widget, QGridLayout * layout );
......@@ -135,6 +136,7 @@ private:
Okular::TextAnnotation * m_textAnn;
PixmapPreviewSelector * m_pixmapSelector { nullptr };
KFontRequester * m_fontReq { nullptr };
KColorButton *m_textColorBn { nullptr };
QComboBox * m_textAlign { nullptr };
QDoubleSpinBox * m_spinWidth { nullptr };
};
......
......@@ -73,7 +73,7 @@ Engine/Annotation Types [specific attributes]:
</tool>
<tool id="10" type="typewriter">
<engine type="PickPoint" block="true">
<annotation type="Typewriter" color="#00ffffff" width="0" />
<annotation type="Typewriter" color="#00ffffff" textColor="#ff000000" width="0" />
</engine>
</tool>
</annotatingTools>
......@@ -686,6 +686,7 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
image.fill( acolor.rgba() );
QPainter painter( &image );
painter.setFont( text->textFont() );
painter.setPen( text->textColor() );
Qt::AlignmentFlag halign = ( text->inplaceAlignment() == 1 ? Qt::AlignHCenter : ( text->inplaceAlignment() == 2 ? Qt::AlignRight : Qt::AlignLeft ) );
const double invXScale = (double)page->width() / scaledWidth;
const double invYScale = (double)page->height() / scaledHeight;
......
......@@ -159,6 +159,14 @@ class PickPointEngine : public AnnotatorEngine
f.fromString( m_annotElement.attribute( QStringLiteral("font") ) );
ta->setTextFont( f );
}
// set font color
if ( m_annotElement.hasAttribute( QStringLiteral("textColor") ) )
{
if ( inplaceIntent == Okular::TextAnnotation::TypeWriter )
ta->setTextColor( m_annotElement.attribute( QStringLiteral("textColor") ) );
else
ta->setTextColor( Qt::black );
}
//set width
if ( m_annotElement.hasAttribute( QStringLiteral ( "width" ) ) )
{
......@@ -1121,7 +1129,7 @@ QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
pixmap.load( QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString("okular/pics/tool-base-okular" + imageVariant + ".png") ) );
/* Parse color, innerColor and icon (if present) */
QColor engineColor, innerColor, annotColor;
QColor engineColor, innerColor, textColor, annotColor;
QString icon;
QDomNodeList engineNodeList = toolElement.elementsByTagName( QStringLiteral("engine") );
if ( engineNodeList.size() > 0 )
......@@ -1134,12 +1142,17 @@ QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
if ( annotationNodeList.size() > 0 )
{
QDomElement annotationEl = annotationNodeList.item( 0 ).toElement();
if ( !annotationEl.isNull() && annotationEl.hasAttribute( QStringLiteral("color") ) )
annotColor = annotationEl.attribute( QStringLiteral("color") );
if ( !annotationEl.isNull() && annotationEl.hasAttribute( QStringLiteral("innerColor") ) )
innerColor = QColor( annotationEl.attribute( QStringLiteral("innerColor") ) );
if ( !annotationEl.isNull() && annotationEl.hasAttribute( QStringLiteral("icon") ) )
icon = annotationEl.attribute( QStringLiteral("icon") );
if ( !annotationEl.isNull() )
{
if ( annotationEl.hasAttribute( QStringLiteral("color") ) )
annotColor = annotationEl.attribute( QStringLiteral("color") );
if ( annotationEl.hasAttribute( QStringLiteral("innerColor") ) )
innerColor = QColor( annotationEl.attribute( QStringLiteral("innerColor") ) );
if ( annotationEl.hasAttribute( QStringLiteral("textColor") ) )
textColor = QColor( annotationEl.attribute( QStringLiteral("textColor") ) );
if ( annotationEl.hasAttribute( QStringLiteral("icon") ) )
icon = annotationEl.attribute( QStringLiteral("icon") );
}
}
QPainter p( &pixmap );
......@@ -1248,8 +1261,7 @@ QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
else if ( annotType == QLatin1String("typewriter") )
{
QImage overlay( QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString("okular/pics/tool-typewriter-okular-colorizable" + imageVariant + ".png") ) );
/* Here we want to colorize the icon with font color instead of background color. Font color is black a.t.m. */
GuiUtils::colorizeImage( overlay, Qt::black );
GuiUtils::colorizeImage( overlay, textColor );
p.drawImage( QPoint(-2,2), overlay );
}
else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment