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