[Digikam-devel] extragear/graphics/digikamimageplugins/inserttext

Marcel Wiesweg marcel.wiesweg at gmx.de
Thu Mar 30 16:07:00 BST 2006


SVN commit 524519 by mwiesweg:

digikam from trunk:
Remember position of text in "Insert Text" plugin

The code tries to be a bit "smart" for images of different size,
it stores relative values and aligns the text rectangle along
the edges it is closer to. So something like "in the bottom
left corner" should be remembered across images.

CCMAIL: digikam-devel at kde.org



 M  +10 -8     imageeffect_inserttext.cpp  
 M  +99 -4     inserttextwidget.cpp  
 M  +5 -1      inserttextwidget.h  


--- trunk/extragear/graphics/digikamimageplugins/inserttext/imageeffect_inserttext.cpp #524518:524519
@@ -227,13 +227,13 @@
     config->setGroup("Insert Text Tool Settings");
     QColor *black = new QColor( 0, 0, 0 );
     QFont *defaultFont = new QFont();
-    
+
     int orgW = m_previewWidget->imageIface()->originalWidth();
     int orgH = m_previewWidget->imageIface()->originalHeight();
-    
+
     if ( orgW > orgH ) m_defaultSizeFont = (int)(orgH / 8.0);
     else m_defaultSizeFont = (int)(orgW / 8.0);
-    
+
     defaultFont->setPointSize( m_defaultSizeFont );
     m_textRotation->setCurrentItem( config->readNumEntry("Text Rotation", 0) );
     m_fontColorButton->setColor(config->readColorEntry("Font Color", black));
@@ -243,19 +243,20 @@
     m_alignTextMode = config->readNumEntry("Text Alignment", ALIGN_LEFT);
     m_borderText->setChecked( config->readBoolEntry("Border Text", false) );
     m_transparentText->setChecked( config->readBoolEntry("Transparent Text", false) );
-    
+    m_previewWidget->setPositionHint( config->readRectEntry("Position Hint") );
+
     delete black;
     delete defaultFont;
-    
+
     static_cast<QPushButton*>(m_alignButtonGroup->find(m_alignTextMode))->setOn(true);
     slotAlignModeChanged(m_alignTextMode);
 }
-    
+
 void ImageEffect_InsertText::writeSettings(void)
 {
     KConfig *config = kapp->config();
     config->setGroup("Insert Text Tool Settings");
-    
+
     config->writeEntry( "Text Rotation", m_textRotation->currentItem() );
     config->writeEntry( "Font Color", m_fontColorButton->color() );
     config->writeEntry( "Text String", m_textEdit->text() );
@@ -263,7 +264,8 @@
     config->writeEntry( "Text Alignment", m_alignTextMode );
     config->writeEntry( "Border Text", m_borderText->isChecked() );
     config->writeEntry( "Transparent Text", m_transparentText->isChecked() );
-    
+    config->writeEntry( "Position Hint", m_previewWidget->getPositionHint() );
+
     config->sync();
 }
 
--- trunk/extragear/graphics/digikamimageplugins/inserttext/inserttextwidget.cpp #524518:524519
@@ -138,6 +138,33 @@
     repaint(false);
 }
 
+void InsertTextWidget::setPositionHint(QRect hint)
+{
+    // interpreted by composeImage
+    m_positionHint = hint;
+    if (m_textRect.isValid())
+    {
+        // invalidate current position so that hint is certainly interpreted
+        m_textRect = QRect();
+        makePixmap();
+        repaint();
+    }
+}
+
+QRect InsertTextWidget::getPositionHint()
+{
+    QRect hint;
+    if (m_textRect.isValid())
+    {
+        // We normalize on the size of the image, but we store as int. Precision loss is no problem.
+        hint.setX(      (int) ((float)(m_textRect.x() - m_rect.x())     / (float)m_rect.width()  * 10000.0) );
+        hint.setY(      (int) ((float)(m_textRect.y() - m_rect.y())     / (float)m_rect.height() * 10000.0) );
+        hint.setWidth(  (int) ((float)m_textRect.width()  / (float)m_rect.width()  * 10000.0) );
+        hint.setHeight( (int) ((float)m_textRect.height() / (float)m_rect.height() * 10000.0) );
+    }
+    return hint;
+}
+
 Digikam::DImg InsertTextWidget::makeInsertText(void)
 {
     int orgW = m_iface->originalWidth();
@@ -148,6 +175,7 @@
     int x, y;
     if (m_textRect.isValid())
     {
+        // convert from widget to image coordinates, then to original size
         x = lroundf( (m_textRect.x() - m_rect.x()) * ratioW);
         y = lroundf( (m_textRect.y() - m_rect.y()) * ratioH);
     }
@@ -177,10 +205,10 @@
     float ratioW = (float)m_w / (float)orgW;
     float ratioH = (float)m_h / (float)orgH;
 
-    // convert from widget to image coordinates
     int x, y;
     if (m_textRect.isValid())
     {
+        // convert from widget to image coordinates
         x = m_textRect.x() - m_rect.x();
         y = m_textRect.y() - m_rect.y();
     }
@@ -265,8 +293,67 @@
 
     if (x == -1 && y == -1)
     {
-        x = QMAX( (maxWidth - fontRect.width()) / 2, 0);
-        y = QMAX( (maxHeight - fontRect.height()) / 2, 0);
+        if (m_positionHint.isValid())
+        {
+            // We assume that people tend to orient text along the edges,
+            // so we do some guessing so that positions such as "in the lower right corner"
+            // will be remembered across different image sizes.
+
+            // get relative positions
+            float fromTop =          (float)m_positionHint.top()    / 10000.0;
+            float fromBottom = 1.0 - (float)m_positionHint.bottom() / 10000.0;
+            float fromLeft =         (float)m_positionHint.left()   / 10000.0;
+            float fromRight =  1.0 - (float)m_positionHint.right()  / 10000.0;
+
+            // calculate horizontal position
+            if (fromLeft < fromRight)
+            {
+                x = (int)(fromLeft * maxWidth);
+
+                // we are placing from the smaller distance,
+                // so if now the larger distance is actually too small,
+                // fall back to standard placement, nothing to lose.
+                if (x + fontRect.width() > maxWidth)
+                    x = QMAX( (maxWidth - fontRect.width()) / 2, 0);
+            }
+            else
+            {
+                x = maxWidth - (int)(fromRight * maxWidth) - fontRect.width();
+                if ( x < 0 )
+                    x = QMAX( (maxWidth - fontRect.width()) / 2, 0);
+            }
+
+            // calculate vertical position
+            if (fromTop < fromBottom)
+            {
+                y = (int)(fromTop * maxHeight);
+                if (y + fontRect.height() > maxHeight)
+                    y = QMAX( (maxHeight - fontRect.height()) / 2, 0);
+            }
+            else
+            {
+                y = maxHeight - (int)(fromBottom * maxHeight) - fontRect.height();
+                if ( y < 0 )
+                    y = QMAX( (maxHeight - fontRect.height()) / 2, 0);
+            }
+
+            if (! QRect(x, y, fontRect.width(), fontRect.height()).
+                   intersects(QRect(0, 0, maxWidth, maxHeight)) )
+            {
+                // emergency fallback - nothing is visible
+                x = QMAX( (maxWidth - fontRect.width()) / 2, 0);
+                y = QMAX( (maxHeight - fontRect.height()) / 2, 0);
+            }
+
+            // invalidate position hint, use only once
+            m_positionHint = QRect();
+        }
+        else
+        {
+            // use standard position
+            x = QMAX( (maxWidth - fontRect.width()) / 2, 0);
+            y = QMAX( (maxHeight - fontRect.height()) / 2, 0);
+        }
     }
 
     // create a rectangle relative to image
@@ -472,13 +559,21 @@
 
     if (m_textRect.isValid())
     {
+        int textWidth  = m_textRect.width();
+        int textHeight = m_textRect.height();
+
         textX = lroundf( textX * (float)m_w / (float)old_w );
         textY = lroundf( textY * (float)m_h / (float)old_h );
+        textWidth  = lroundf(textWidth  * (float)m_w / (float)old_w );
+        textHeight = lroundf(textHeight * (float)m_h / (float)old_h );
+
         m_textRect.setX(textX + m_rect.x());
         m_textRect.setY(textY + m_rect.y());
+        m_textRect.setWidth(textWidth);
+        m_textRect.setHeight(textHeight);
         makePixmap();
     }
-    
+
     blockSignals(false);
 }
 
--- trunk/extragear/graphics/digikamimageplugins/inserttext/inserttextwidget.h #524518:524519
@@ -90,6 +90,9 @@
                    bool border, bool transparent, int rotation);
     void   resetEdit(void);
 
+    void  setPositionHint(QRect hint);
+    QRect getPositionHint();
+
 private:
 
     Digikam::ImageIface *m_iface;
@@ -122,7 +125,8 @@
     QColor      m_textColor;
 
     QColor      m_backgroundColor;
-    
+
+    QRect       m_positionHint;
 protected:
 
     void paintEvent( QPaintEvent *e );



More information about the Digikam-devel mailing list