00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "KoBorder.h"
00021 #include <qdom.h>
00022 #include <QByteArray>
00023 #include <kdebug.h>
00024 #include "KoZoomHandler.h"
00025 #include "KoTextFormat.h"
00026 #include "KoRichText.h"
00027 #include "KoTextParag.h"
00028 #include "KoUnit.h"
00029 #include <float.h>
00030
00031 static const struct BorderStyle {
00032 Qt::PenStyle penStyle;
00033 QByteArray oasisName;
00034 QByteArray uiStringStyle;
00035 } s_borderStyles[] = {
00036 { Qt::SolidLine, "solid", "_________" },
00037 { Qt::DashLine, "dashed", "___ ___ __" },
00038 { Qt::DotLine, "dotted", "_ _ _ _ _ _" },
00039 { Qt::DashDotLine, "dot-dash", "___ _ ___ _" },
00040 { Qt::DashDotDotLine, "dot-dot-dash", "___ _ _ ___" },
00041 { Qt::SolidLine, "double", "===========" }
00042 };
00043
00044 KoBorder::KoBorder()
00045 : color(), m_style( SOLID )
00046 {
00047 setPenWidth( 1 );
00048 }
00049
00050 KoBorder::KoBorder( const QColor & c, BorderStyle s, double width )
00051 : color( c ), m_style( s )
00052 {
00053 setPenWidth( width );
00054 }
00055
00056 bool KoBorder::operator==( const KoBorder _brd ) const {
00057 return ( m_style == _brd.m_style && color == _brd.color && ptPenWidth == _brd.ptPenWidth );
00058 }
00059
00060 bool KoBorder::operator!=( const KoBorder _brd ) const {
00061 return ( m_style != _brd.m_style || color != _brd.color || ptPenWidth != _brd.ptPenWidth );
00062 }
00063
00064 void KoBorder::setStyle(BorderStyle _style)
00065 {
00066 m_style = _style;
00067 setPenWidth( ptPenWidth );
00068 }
00069
00070 void KoBorder::setPenWidth(double _w)
00071 {
00072 ptPenWidth = _w;
00073 if ( m_style == KoBorder::DOUBLE_LINE && _w > 0 )
00074 ptWidth = 2 * ptPenWidth + 1;
00075 else
00076 ptWidth = _w;
00077 }
00078
00079 QPen KoBorder::borderPen( const KoBorder & _brd, int width, QColor defaultColor )
00080 {
00081 QPen pen( _brd.color, width );
00082 if ( !_brd.color.isValid() )
00083 pen.setColor( defaultColor );
00084
00085 pen.setStyle( s_borderStyles[ _brd.m_style ].penStyle );
00086
00087 return pen;
00088 }
00089
00090
00091 KoBorder KoBorder::loadBorder( const QDomElement & elem )
00092 {
00093 KoBorder bd;
00094 if ( elem.hasAttribute("red") )
00095 {
00096 int r = elem.attribute("red").toInt();
00097 int g = elem.attribute("green").toInt();
00098 int b = elem.attribute("blue").toInt();
00099 bd.color.setRgb( r, g, b );
00100 }
00101 bd.m_style = static_cast<BorderStyle>( elem.attribute("style").toInt() );
00102 bd.setPenWidth( elem.attribute("width").toDouble() );
00103 return bd;
00104 }
00105
00106 void KoBorder::loadFoBorder( const QString& border )
00107 {
00108
00109
00110 if (border.isEmpty() || border=="none" || border=="hidden") {
00111 setPenWidth( 0 );
00112 return;
00113 }
00114
00115
00116 QString _width = border.section(' ', 0, 0);
00117 QByteArray _style = border.section(' ', 1, 1).toLatin1();
00118 QString _color = border.section(' ', 2, 2);
00119
00120
00121 double const penWidth = KoUnit::parseValue( _width, 1.0 );
00122
00123 if ( penWidth < 1.5 )
00124 setPenWidth( 1.0 );
00125 else if ( penWidth < 2.5 )
00126 setPenWidth( 2.0 );
00127 else if ( penWidth < 3.5 )
00128 setPenWidth( 3.0 );
00129 else if ( penWidth < 4.5 )
00130 setPenWidth( 4.0 );
00131 else if ( penWidth < 5.5 )
00132 setPenWidth( 5.0 );
00133 else if ( penWidth < 6.5 )
00134 setPenWidth( 6.0 );
00135 else if ( penWidth < 7.5 )
00136 setPenWidth( 7.0 );
00137 else if ( penWidth < 8.5 )
00138 setPenWidth( 8.0 );
00139 else if ( penWidth < 9.5 )
00140 setPenWidth( 9.0 );
00141 else
00142 setPenWidth( 10.0 );
00143
00144 m_style = SOLID;
00145 for ( uint i = 0; i < sizeof( s_borderStyles ) / sizeof *s_borderStyles; ++i ) {
00146 if ( _style == s_borderStyles[i].oasisName )
00147 m_style = static_cast<BorderStyle>( i );
00148 }
00149
00150 if ( _color.isEmpty() )
00151 color = QColor();
00152 else
00153 color.setNamedColor( _color );
00154 }
00155
00156 QString KoBorder::saveFoBorder() const
00157 {
00158 if ( QABS( ptPenWidth ) < 1E-10 )
00159 return "none";
00160
00161 QString str = QString::number( ptPenWidth, 'g', DBL_DIG );
00162 str += "pt ";
00163 str += s_borderStyles[ m_style ].oasisName;
00164 if ( color.isValid() ) {
00165 str += ' ';
00166 str += color.name();
00167 }
00168 return str;
00169 }
00170
00171
00172 void KoBorder::save( QDomElement & elem ) const
00173 {
00174 if (color.isValid()) {
00175 elem.setAttribute("red", color.red());
00176 elem.setAttribute("green", color.green());
00177 elem.setAttribute("blue", color.blue());
00178 }
00179 elem.setAttribute("style", static_cast<int>( m_style ));
00180 elem.setAttribute("width", ptPenWidth);
00181 }
00182
00183 KoBorder::BorderStyle KoBorder::getStyle( const QString &style )
00184 {
00185 for ( uint i = 0; i < sizeof( s_borderStyles ) / sizeof *s_borderStyles; ++i ) {
00186 if ( style == s_borderStyles[i].uiStringStyle.data() )
00187 return static_cast<BorderStyle>( i );
00188 }
00189
00190 return KoBorder::SOLID;
00191 }
00192
00193 QString KoBorder::getStyle( const BorderStyle &style )
00194 {
00195 return s_borderStyles[style].uiStringStyle;
00196 }
00197
00198 int KoBorder::zoomWidthX( double ptWidth, KoZoomHandler * zoomHandler, int minborder )
00199 {
00200
00201
00202 return ptWidth > 0 ? qMax( 1, zoomHandler->zoomItXOld( ptWidth ) ) : minborder;
00203 }
00204
00205 int KoBorder::zoomWidthY( double ptWidth, KoZoomHandler * zoomHandler, int minborder )
00206 {
00207
00208
00209 return ptWidth > 0 ? qMax( 1, zoomHandler->zoomItYOld( ptWidth ) ) : minborder;
00210 }
00211
00212 void KoBorder::drawBorders( QPainter& painter, KoZoomHandler * zoomHandler, const QRect& rect, const KoBorder& leftBorder, const KoBorder& rightBorder, const KoBorder& topBorder, const KoBorder& bottomBorder, int minborder, const QPen& defaultPen, bool drawTopBorder , bool drawBottomBorder )
00213 {
00214 int topBorderWidth = zoomWidthY( topBorder.width(), zoomHandler, minborder );
00215 int bottomBorderWidth = zoomWidthY( bottomBorder.width(), zoomHandler, minborder );
00216 int leftBorderWidth = zoomWidthX( leftBorder.width(), zoomHandler, minborder );
00217 int rightBorderWidth = zoomWidthX( rightBorder.width(), zoomHandler, minborder );
00218
00219 int topBorderPenWidth = zoomWidthY( topBorder.penWidth(), zoomHandler, minborder );
00220 int bottomBorderPenWidth = zoomWidthY( bottomBorder.penWidth(), zoomHandler, minborder );
00221 int leftBorderPenWidth = zoomWidthX( leftBorder.penWidth(), zoomHandler, minborder );
00222 int rightBorderPenWidth = zoomWidthX( rightBorder.penWidth(), zoomHandler, minborder );
00223
00224
00225 int lastPixelAdj = 1;
00226
00227
00228
00229
00230
00231
00232
00233 QColor defaultColor = KoTextFormat::defaultTextColor( &painter );
00234
00235 if ( topBorderWidth > 0 && drawTopBorder )
00236 {
00237 if ( topBorder.penWidth() > 0 )
00238 painter.setPen( KoBorder::borderPen( topBorder, topBorderPenWidth, defaultColor ) );
00239 else
00240 painter.setPen( defaultPen );
00241 int y = rect.top() - topBorderWidth + topBorderPenWidth/2;
00242 if ( topBorder.m_style==KoBorder::DOUBLE_LINE)
00243 {
00244 painter.drawLine( rect.left()-leftBorderWidth, y, rect.right()+2*(rightBorderPenWidth+lastPixelAdj), y );
00245 y += topBorderPenWidth + 1;
00246 painter.drawLine( rect.left()-leftBorderPenWidth, y, rect.right()+rightBorderPenWidth+lastPixelAdj, y );
00247 }
00248 else
00249 {
00250 painter.drawLine( rect.left()-leftBorderWidth, y, rect.right()+rightBorderWidth+lastPixelAdj, y );
00251 }
00252 }
00253 if ( bottomBorderWidth > 0 && drawBottomBorder )
00254 {
00255 if ( bottomBorder.penWidth() > 0 )
00256 painter.setPen( KoBorder::borderPen( bottomBorder, bottomBorderPenWidth, defaultColor ) );
00257 else
00258 painter.setPen( defaultPen );
00259
00260 int y = rect.bottom() + bottomBorderPenWidth/2 + 1;
00261
00262 if ( bottomBorder.m_style==KoBorder::DOUBLE_LINE)
00263 {
00264 painter.drawLine( rect.left()-leftBorderPenWidth, y, rect.right()+rightBorderPenWidth+lastPixelAdj, y );
00265 y += bottomBorderPenWidth + 1;
00266 painter.drawLine( rect.left()-leftBorderWidth, y, rect.right()+2*(rightBorderPenWidth+lastPixelAdj), y );
00267 }
00268 else
00269 {
00270 painter.drawLine( rect.left()-leftBorderWidth, y, rect.right()+rightBorderWidth+lastPixelAdj, y );
00271 }
00272 }
00273 if ( leftBorderWidth > 0 )
00274 {
00275 if ( leftBorder.penWidth() > 0 )
00276 painter.setPen( KoBorder::borderPen( leftBorder, leftBorderPenWidth, defaultColor ) );
00277 else
00278 painter.setPen( defaultPen );
00279 int x = rect.left() - leftBorderWidth + leftBorderPenWidth/2;
00280 if ( leftBorder.m_style==KoBorder::DOUBLE_LINE)
00281 {
00282 painter.drawLine( x, rect.top()-topBorderWidth, x, rect.bottom()+2*(bottomBorderPenWidth+lastPixelAdj) );
00283 x += leftBorderPenWidth + 1;
00284 painter.drawLine( x, rect.top()-topBorderPenWidth, x, rect.bottom()+bottomBorderPenWidth+lastPixelAdj );
00285 }
00286 else
00287 {
00288 int yTop = rect.top() - topBorderWidth;
00289 int yBottom = rect.bottom() + bottomBorderWidth;
00290
00291
00292
00293 painter.drawLine( x, yTop, x, yBottom+lastPixelAdj );
00294 }
00295 }
00296 if ( rightBorderWidth > 0 )
00297 {
00298 if ( rightBorder.penWidth() > 0 )
00299 painter.setPen( KoBorder::borderPen( rightBorder, rightBorderPenWidth, defaultColor ) );
00300 else
00301 painter.setPen( defaultPen );
00302 int x = rect.right() + rightBorderPenWidth/2 + 1;
00303 if ( rightBorder.m_style==KoBorder::DOUBLE_LINE)
00304 {
00305 painter.drawLine( x, rect.top()-topBorderPenWidth, x, rect.bottom()+bottomBorderPenWidth+lastPixelAdj );
00306 x += rightBorderPenWidth + 1;
00307 painter.drawLine( x, rect.top()-topBorderWidth, x, rect.bottom()+2*(bottomBorderPenWidth+lastPixelAdj) );
00308
00309 }
00310 else
00311 {
00312 int yTop = rect.top()-topBorderWidth;
00313 int yBottom = rect.bottom()+bottomBorderWidth+lastPixelAdj;
00314
00315
00316
00317 painter.drawLine( x, yTop, x, yBottom );
00318 }
00319 }
00320 }