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