1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_drawinglayer.hxx" 30 31 #include <drawinglayer/primitive2d/textlineprimitive2d.hxx> 32 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 33 #include <drawinglayer/attribute/strokeattribute.hxx> 34 #include <drawinglayer/attribute/lineattribute.hxx> 35 #include <basegfx/matrix/b2dhommatrixtools.hxx> 36 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> 37 #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 38 39 ////////////////////////////////////////////////////////////////////////////// 40 41 namespace drawinglayer 42 { 43 namespace primitive2d 44 { 45 Primitive2DSequence TextLinePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const 46 { 47 Primitive2DSequence xRetval; 48 49 if(TEXT_LINE_NONE != getTextLine()) 50 { 51 bool bDoubleLine(false); 52 bool bWaveLine(false); 53 bool bBoldLine(false); 54 const int* pDotDashArray(0); 55 basegfx::B2DLineJoin eLineJoin(basegfx::B2DLINEJOIN_NONE); 56 double fOffset(getOffset()); 57 double fHeight(getHeight()); 58 59 static const int aDottedArray[] = { 1, 1, 0}; // DOTTED LINE 60 static const int aDotDashArray[] = { 1, 1, 4, 1, 0}; // DASHDOT 61 static const int aDashDotDotArray[] = { 1, 1, 1, 1, 4, 1, 0}; // DASHDOTDOT 62 static const int aDashedArray[] = { 5, 2, 0}; // DASHED LINE 63 static const int aLongDashArray[] = { 7, 2, 0}; // LONGDASH 64 65 // get decomposition 66 basegfx::B2DVector aScale, aTranslate; 67 double fRotate, fShearX; 68 getObjectTransformation().decompose(aScale, aTranslate, fRotate, fShearX); 69 70 switch(getTextLine()) 71 { 72 default: // case TEXT_LINE_SINGLE: 73 { 74 break; 75 } 76 case TEXT_LINE_DOUBLE: 77 { 78 bDoubleLine = true; 79 break; 80 } 81 case TEXT_LINE_DOTTED: 82 { 83 pDotDashArray = aDottedArray; 84 break; 85 } 86 case TEXT_LINE_DASH: 87 { 88 pDotDashArray = aDashedArray; 89 break; 90 } 91 case TEXT_LINE_LONGDASH: 92 { 93 pDotDashArray = aLongDashArray; 94 break; 95 } 96 case TEXT_LINE_DASHDOT: 97 { 98 pDotDashArray = aDotDashArray; 99 break; 100 } 101 case TEXT_LINE_DASHDOTDOT: 102 { 103 pDotDashArray = aDashDotDotArray; 104 break; 105 } 106 case TEXT_LINE_SMALLWAVE: 107 { 108 bWaveLine = true; 109 break; 110 } 111 case TEXT_LINE_WAVE: 112 { 113 bWaveLine = true; 114 break; 115 } 116 case TEXT_LINE_DOUBLEWAVE: 117 { 118 bDoubleLine = true; 119 bWaveLine = true; 120 break; 121 } 122 case TEXT_LINE_BOLD: 123 { 124 bBoldLine = true; 125 break; 126 } 127 case TEXT_LINE_BOLDDOTTED: 128 { 129 bBoldLine = true; 130 pDotDashArray = aDottedArray; 131 break; 132 } 133 case TEXT_LINE_BOLDDASH: 134 { 135 bBoldLine = true; 136 pDotDashArray = aDashedArray; 137 break; 138 } 139 case TEXT_LINE_BOLDLONGDASH: 140 { 141 bBoldLine = true; 142 pDotDashArray = aLongDashArray; 143 break; 144 } 145 case TEXT_LINE_BOLDDASHDOT: 146 { 147 bBoldLine = true; 148 pDotDashArray = aDotDashArray; 149 break; 150 } 151 case TEXT_LINE_BOLDDASHDOTDOT: 152 { 153 bBoldLine = true; 154 pDotDashArray = aDashDotDotArray; 155 break; 156 } 157 case TEXT_LINE_BOLDWAVE: 158 { 159 bWaveLine = true; 160 bBoldLine = true; 161 break; 162 } 163 } 164 165 if(bBoldLine) 166 { 167 fHeight *= 2.0; 168 } 169 170 if(bDoubleLine) 171 { 172 fOffset -= 0.50 * fHeight; 173 fHeight *= 0.64; 174 } 175 176 if(bWaveLine) 177 { 178 eLineJoin = basegfx::B2DLINEJOIN_ROUND; 179 fHeight *= 0.25; 180 } 181 182 // prepare Line and Stroke Attributes 183 const attribute::LineAttribute aLineAttribute(getLineColor(), fHeight, eLineJoin); 184 attribute::StrokeAttribute aStrokeAttribute; 185 186 if(pDotDashArray) 187 { 188 ::std::vector< double > aDoubleArray; 189 190 for(const int* p = pDotDashArray; *p; ++p) 191 { 192 aDoubleArray.push_back((double)(*p) * fHeight); 193 } 194 195 aStrokeAttribute = attribute::StrokeAttribute(aDoubleArray); 196 } 197 198 // create base polygon and new primitive 199 basegfx::B2DPolygon aLine; 200 Primitive2DReference aNewPrimitive; 201 202 aLine.append(basegfx::B2DPoint(0.0, fOffset)); 203 aLine.append(basegfx::B2DPoint(getWidth(), fOffset)); 204 205 const basegfx::B2DHomMatrix aUnscaledTransform( 206 basegfx::tools::createShearXRotateTranslateB2DHomMatrix( 207 fShearX, fRotate, aTranslate)); 208 209 aLine.transform(aUnscaledTransform); 210 211 if(bWaveLine) 212 { 213 double fWaveWidth(10.6 * fHeight); 214 215 if(TEXT_LINE_SMALLWAVE == getTextLine()) 216 { 217 fWaveWidth *= 0.7; 218 } 219 else if(TEXT_LINE_WAVE == getTextLine()) 220 { 221 // extra multiply to get the same WaveWidth as with the bold version 222 fWaveWidth *= 2.0; 223 } 224 225 aNewPrimitive = Primitive2DReference(new PolygonWavePrimitive2D(aLine, aLineAttribute, aStrokeAttribute, fWaveWidth, fWaveWidth * 0.5)); 226 } 227 else 228 { 229 aNewPrimitive = Primitive2DReference(new PolygonStrokePrimitive2D(aLine, aLineAttribute, aStrokeAttribute)); 230 } 231 232 // add primitive 233 appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, aNewPrimitive); 234 235 if(bDoubleLine) 236 { 237 // double line, create 2nd primitive with offset using TransformPrimitive based on 238 // already created NewPrimitive 239 double fLineDist(2.3 * fHeight); 240 241 if(bWaveLine) 242 { 243 fLineDist = 6.3 * fHeight; 244 } 245 246 // move base point of text to 0.0 and de-rotate 247 basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix( 248 -aTranslate.getX(), -aTranslate.getY())); 249 aTransform.rotate(-fRotate); 250 251 // translate in Y by offset 252 aTransform.translate(0.0, fLineDist); 253 254 // move back and rotate 255 aTransform.rotate(fRotate); 256 aTransform.translate(aTranslate.getX(), aTranslate.getY()); 257 258 // add transform primitive 259 const Primitive2DSequence aContent(&aNewPrimitive, 1); 260 appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, 261 Primitive2DReference(new TransformPrimitive2D(aTransform, aContent))); 262 } 263 } 264 265 return xRetval; 266 } 267 268 TextLinePrimitive2D::TextLinePrimitive2D( 269 const basegfx::B2DHomMatrix& rObjectTransformation, 270 double fWidth, 271 double fOffset, 272 double fHeight, 273 TextLine eTextLine, 274 const basegfx::BColor& rLineColor) 275 : BufferedDecompositionPrimitive2D(), 276 maObjectTransformation(rObjectTransformation), 277 mfWidth(fWidth), 278 mfOffset(fOffset), 279 mfHeight(fHeight), 280 meTextLine(eTextLine), 281 maLineColor(rLineColor) 282 { 283 } 284 285 bool TextLinePrimitive2D::operator==( const BasePrimitive2D& rPrimitive ) const 286 { 287 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 288 { 289 const TextLinePrimitive2D& rCompare = (TextLinePrimitive2D&)rPrimitive; 290 291 return (getObjectTransformation() == rCompare.getObjectTransformation() 292 && getWidth() == rCompare.getWidth() 293 && getOffset() == rCompare.getOffset() 294 && getHeight() == rCompare.getHeight() 295 && getTextLine() == rCompare.getTextLine() 296 && getLineColor() == rCompare.getLineColor()); 297 } 298 299 return false; 300 } 301 302 // provide unique ID 303 ImplPrimitrive2DIDBlock(TextLinePrimitive2D, PRIMITIVE2D_ID_TEXTLINEPRIMITIVE2D) 304 305 } // end of namespace primitive2d 306 } // end of namespace drawinglayer 307 308 ////////////////////////////////////////////////////////////////////////////// 309 // eof 310