1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 #ifndef _XMLOFF_SHAPEEXPORT_HXX_ 24 #define _XMLOFF_SHAPEEXPORT_HXX_ 25 26 #include "sal/config.h" 27 #include "xmloff/dllapi.h" 28 #include "sal/types.h" 29 30 #include <rtl/ref.hxx> 31 #include <rtl/ustring.hxx> 32 #include <rtl/ustrbuf.hxx> 33 #include <xmloff/uniref.hxx> 34 35 #include <com/sun/star/drawing/XShape.hpp> 36 #include <com/sun/star/drawing/XShapes.hpp> 37 #include <com/sun/star/awt/Point.hpp> 38 #include <com/sun/star/beans/PropertyValue.hpp> 39 40 #include <map> 41 #include <xmloff/xmlprmap.hxx> 42 #include <xmloff/xmlexppr.hxx> 43 #include <xmloff/animexp.hxx> 44 #include <xmloff/families.hxx> 45 46 #include "xmloff/table/XMLTableExport.hxx" 47 48 // shape export features are bits used for the nFeature 49 // parameter of XMLShapeExport::exportShape 50 51 #define SEF_EXPORT_X 0x0001 52 #define SEF_EXPORT_Y 0x0002 53 #define SEF_EXPORT_POSITION 0x0003 54 55 #define SEF_EXPORT_WIDTH 0x0004 56 #define SEF_EXPORT_HEIGHT 0x0008 57 #define SEF_EXPORT_SIZE 0x000c 58 59 // when you set this flag a chart does NOT export its own data as table element 60 #define SEF_EXPORT_NO_CHART_DATA 0x0010 61 62 // When setting the flag below no ignorableWhiteSpace will be called around 63 // the drawing object elements 64 #define SEF_EXPORT_NO_WS 0x0020 65 66 // When setting the flag below a callout shape is exported as office:annotation 67 #define SEF_EXPORT_ANNOTATION 0x0040 68 69 #define SEF_DEFAULT SEF_EXPORT_POSITION|SEF_EXPORT_SIZE 70 71 enum XmlShapeType 72 { 73 XmlShapeTypeUnknown, // not known 74 75 XmlShapeTypeDrawRectangleShape, // "com.sun.star.drawing.RectangleShape" 76 XmlShapeTypeDrawEllipseShape, // "com.sun.star.drawing.EllipseShape" 77 XmlShapeTypeDrawControlShape, // "com.sun.star.drawing.ControlShape" 78 XmlShapeTypeDrawConnectorShape, // "com.sun.star.drawing.ConnectorShape" 79 XmlShapeTypeDrawMeasureShape, // "com.sun.star.drawing.MeasureShape" 80 XmlShapeTypeDrawLineShape, // "com.sun.star.drawing.LineShape" 81 XmlShapeTypeDrawPolyPolygonShape, // "com.sun.star.drawing.PolyPolygonShape" 82 XmlShapeTypeDrawPolyLineShape, // "com.sun.star.drawing.PolyLineShape" 83 XmlShapeTypeDrawOpenBezierShape, // "com.sun.star.drawing.OpenBezierShape" 84 XmlShapeTypeDrawClosedBezierShape, // "com.sun.star.drawing.ClosedBezierShape" 85 XmlShapeTypeDrawGraphicObjectShape, // "com.sun.star.drawing.GraphicObjectShape" 86 XmlShapeTypeDrawGroupShape, // "com.sun.star.drawing.GroupShape" 87 XmlShapeTypeDrawTextShape, // "com.sun.star.drawing.TextShape" 88 XmlShapeTypeDrawOLE2Shape, // "com.sun.star.drawing.OLE2Shape" 89 XmlShapeTypeDrawChartShape, // embedded com.sun.star.chart 90 XmlShapeTypeDrawSheetShape, // embedded com.sun.star.sheet 91 XmlShapeTypeDrawPageShape, // "com.sun.star.drawing.PageShape" 92 XmlShapeTypeDrawFrameShape, // "com.sun.star.drawing.FrameShape" 93 XmlShapeTypeDrawCaptionShape, // "com.sun.star.drawing.CaptionShape" 94 XmlShapeTypeDrawAppletShape, // "com.sun.star.drawing.AppletShape" 95 XmlShapeTypeDrawPluginShape, // "com.sun.star.drawing.PlugginShape" 96 97 XmlShapeTypeDraw3DSceneObject, // "com.sun.star.drawing.Shape3DSceneObject" 98 XmlShapeTypeDraw3DCubeObject, // "com.sun.star.drawing.Shape3DCubeObject" 99 XmlShapeTypeDraw3DSphereObject, // "com.sun.star.drawing.Shape3DSphereObject" 100 XmlShapeTypeDraw3DLatheObject, // "com.sun.star.drawing.Shape3DLatheObject" 101 XmlShapeTypeDraw3DExtrudeObject, // "com.sun.star.drawing.Shape3DExtrudeObject" 102 103 XmlShapeTypePresTitleTextShape, // "com.sun.star.presentation.TitleTextShape" 104 XmlShapeTypePresOutlinerShape, // "com.sun.star.presentation.OutlinerShape" 105 XmlShapeTypePresSubtitleShape, // "com.sun.star.presentation.SubtitleShape" 106 XmlShapeTypePresGraphicObjectShape, // "com.sun.star.presentation.GraphicObjectShape" 107 XmlShapeTypePresPageShape, // "com.sun.star.presentation.PageShape" 108 XmlShapeTypePresOLE2Shape, // "com.sun.star.presentation.OLE2Shape" 109 XmlShapeTypePresChartShape, // "com.sun.star.presentation.ChartShape" 110 XmlShapeTypePresSheetShape, // "com.sun.star.presentation.CalcShape" 111 XmlShapeTypePresTableShape, // "com.sun.star.presentation.TableShape" 112 XmlShapeTypePresOrgChartShape, // "com.sun.star.presentation.OrgChartShape" 113 XmlShapeTypePresNotesShape, // "com.sun.star.presentation.NotesShape" 114 XmlShapeTypeHandoutShape, // "com.sun.star.presentation.HandoutShape" 115 116 XmlShapeTypePresHeaderShape, // "com.sun.star.presentation.HeaderShape" 117 XmlShapeTypePresFooterShape, // "com.sun.star.presentation.FooterShape" 118 XmlShapeTypePresSlideNumberShape, // "com.sun.star.presentation.SlideNumberShape" 119 XmlShapeTypePresDateTimeShape, // "com.sun.star.presentation.DateTimeShape" 120 121 XmlShapeTypeDrawCustomShape, // "com.sun.star.drawing.CustomShape" 122 XmlShapeTypeDrawMediaShape, // "com.sun.star.drawing.MediaShape" 123 XmlShapeTypePresMediaShape, // "com.sun.star.presentation.MediaShape" 124 125 XmlShapeTypeDrawTableShape, // "com.sun.star.drawing.TableShape" 126 127 XmlShapeTypeNotYetSet 128 }; 129 130 /** caches style and type info after a collectShapeAutostyle for later use in exportShape */ 131 struct ImplXMLShapeExportInfo 132 { 133 rtl::OUString msStyleName; 134 rtl::OUString msTextStyleName; 135 sal_Int32 mnFamily; 136 XmlShapeType meShapeType; 137 138 com::sun::star::uno::Reference< com::sun::star::drawing::XShape > xCustomShapeReplacement; 139 ImplXMLShapeExportInfoImplXMLShapeExportInfo140 ImplXMLShapeExportInfo() : mnFamily( XML_STYLE_FAMILY_SD_GRAPHICS_ID ), meShapeType( XmlShapeTypeNotYetSet ) {} 141 }; 142 143 /** a vector for shape style and type cache information */ 144 typedef std::vector< ImplXMLShapeExportInfo > ImplXMLShapeExportInfoVector; 145 146 /** a map to store all cache data for already collected XShapes */ 147 typedef std::map< com::sun::star::uno::Reference < com::sun::star::drawing::XShapes >, ImplXMLShapeExportInfoVector > ShapesInfos; 148 149 ////////////////////////////////////////////////////////////////////////////// 150 // predeclarations 151 152 class SvXMLExport; 153 class SvXMLExportPropertyMapper; 154 155 namespace basegfx 156 { 157 class B2DTuple; 158 class B2DHomMatrix; 159 } // end of namespace basegfx 160 161 class XMLOFF_DLLPUBLIC XMLShapeExport : public UniRefBase 162 { 163 private: 164 165 SvXMLExport& mrExport; 166 UniReference< XMLPropertyHandlerFactory > mxSdPropHdlFactory; 167 UniReference< SvXMLExportPropertyMapper > mxPropertySetMapper; 168 UniReference< XMLAnimationsExporter > mxAnimationsExporter; 169 sal_Int32 mnNextUniqueShapeId; 170 ShapesInfos maShapesInfos; 171 ShapesInfos::iterator maCurrentShapesIter; 172 sal_Bool mbExportLayer; 173 ImplXMLShapeExportInfoVector maShapeInfos; 174 ImplXMLShapeExportInfoVector::iterator maCurrentInfo; 175 rtl::OUString msPresentationStylePrefix; 176 177 // #88546# possibility to swich progress bar handling on/off 178 sal_Bool mbHandleProgressBar; 179 180 rtl::Reference< XMLTableExport > mxShapeTableExport; 181 182 protected: GetExport()183 SvXMLExport& GetExport() { return mrExport; } GetExport() const184 const SvXMLExport& GetExport() const { return mrExport; } 185 private: 186 GetPropertySetMapper() const187 SAL_DLLPRIVATE UniReference< SvXMLExportPropertyMapper > GetPropertySetMapper() const { return mxPropertySetMapper; } 188 189 const rtl::OUString msZIndex; 190 const rtl::OUString msPrintable; 191 const rtl::OUString msVisible; 192 193 const rtl::OUString msEmptyPres; 194 const rtl::OUString msModel; 195 const rtl::OUString msStartShape; 196 const rtl::OUString msEndShape; 197 const rtl::OUString msOnClick; 198 #ifdef ISSUE66550_HLINK_FOR_SHAPES 199 const rtl::OUString msOnAction; 200 const rtl::OUString msAction; 201 const rtl::OUString msURL; 202 #endif 203 const rtl::OUString msEventType; 204 const rtl::OUString msPresentation; 205 const rtl::OUString msMacroName; 206 const rtl::OUString msScript; 207 const rtl::OUString msLibrary; 208 const rtl::OUString msClickAction; 209 const rtl::OUString msBookmark; 210 const rtl::OUString msEffect; 211 const rtl::OUString msPlayFull; 212 const rtl::OUString msVerb; 213 const rtl::OUString msSoundURL; 214 const rtl::OUString msSpeed; 215 const rtl::OUString msStarBasic; 216 217 rtl::OUStringBuffer msBuffer; 218 219 SAL_DLLPRIVATE void ImpCalcShapeType(const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType& eShapeType); 220 221 SAL_DLLPRIVATE void ImpExportNewTrans(const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet, sal_Int32 nFeatures, com::sun::star::awt::Point* pRefPoint); 222 SAL_DLLPRIVATE void ImpExportNewTrans_GetB2DHomMatrix(::basegfx::B2DHomMatrix& rMatrix, const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet); 223 SAL_DLLPRIVATE void ImpExportNewTrans_DecomposeAndRefPoint(const ::basegfx::B2DHomMatrix& rMat, ::basegfx::B2DTuple& rTRScale, double& fTRShear, double& fTRRotate, ::basegfx::B2DTuple& rTRTranslate, com::sun::star::awt::Point* pRefPoint); 224 SAL_DLLPRIVATE void ImpExportNewTrans_FeaturesAndWrite(::basegfx::B2DTuple& rTRScale, double fTRShear, double fTRRotate, ::basegfx::B2DTuple& rTRTranslate, const sal_Int32 nFeatures); 225 SAL_DLLPRIVATE sal_Bool ImpExportPresentationAttributes( const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet, const rtl::OUString& rClass ); 226 SAL_DLLPRIVATE void ImpExportText( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape ); 227 SAL_DLLPRIVATE void ImpExportEvents( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape ); 228 SAL_DLLPRIVATE void ImpExportDescription( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape ); // #i68101# 229 SAL_DLLPRIVATE void ImpExportGluePoints( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape ); 230 231 // single shape exporters 232 SAL_DLLPRIVATE void ImpExportGroupShape( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 233 SAL_DLLPRIVATE void ImpExport3DSceneShape( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 234 SAL_DLLPRIVATE void ImpExportRectangleShape( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 235 SAL_DLLPRIVATE void ImpExportLineShape(const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 236 SAL_DLLPRIVATE void ImpExportEllipseShape(const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 237 SAL_DLLPRIVATE void ImpExportPolygonShape(const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 238 SAL_DLLPRIVATE void ImpExportTextBoxShape(const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 239 SAL_DLLPRIVATE void ImpExportGraphicObjectShape(const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 240 SAL_DLLPRIVATE void ImpExportChartShape(const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL, SvXMLAttributeList* pAttrList = NULL ); 241 SAL_DLLPRIVATE void ImpExportControlShape(const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 242 SAL_DLLPRIVATE void ImpExportConnectorShape(const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 243 SAL_DLLPRIVATE void ImpExportMeasureShape(const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 244 SAL_DLLPRIVATE void ImpExportOLE2Shape(const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL, SvXMLAttributeList* pAttrList = NULL ); 245 SAL_DLLPRIVATE void ImpExportPageShape(const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 246 SAL_DLLPRIVATE void ImpExportCaptionShape(const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 247 SAL_DLLPRIVATE void ImpExport3DShape(const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 248 SAL_DLLPRIVATE void ImpExportFrameShape( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 249 SAL_DLLPRIVATE void ImpExportPluginShape( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 250 SAL_DLLPRIVATE void ImpExportAppletShape( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 251 SAL_DLLPRIVATE void ImpExportCustomShape( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 252 SAL_DLLPRIVATE void ImpExportMediaShape( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 253 SAL_DLLPRIVATE void ImpExportTableShape(const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures = SEF_DEFAULT, com::sun::star::awt::Point* pRefPoint = NULL ); 254 public: 255 XMLShapeExport(SvXMLExport& rExp, SvXMLExportPropertyMapper *pExtMapper=0 ); 256 virtual ~XMLShapeExport(); 257 258 // This method collects all automatic styles for the given XShape 259 void collectShapeAutoStyles( 260 const com::sun::star::uno::Reference < com::sun::star::drawing::XShape >& xShape); 261 262 // This method exports the given XShape 263 void exportShape( 264 const com::sun::star::uno::Reference < com::sun::star::drawing::XShape >& xShape, 265 sal_Int32 nFeatures = SEF_DEFAULT, 266 com::sun::star::awt::Point* pRefPoint = NULL, 267 SvXMLAttributeList* pAttrList = NULL 268 ); 269 270 // This method collects all automatic styles for the shapes inside the given XShapes collection 271 void collectShapesAutoStyles( 272 const com::sun::star::uno::Reference < com::sun::star::drawing::XShapes >& xShapes); 273 274 // This method exports all XShape inside the given XShapes collection 275 void exportShapes( 276 const com::sun::star::uno::Reference < com::sun::star::drawing::XShapes >& xShapes, 277 sal_Int32 nFeatures = SEF_DEFAULT, 278 com::sun::star::awt::Point* pRefPoint = NULL 279 ); 280 281 /** initializes some internal structures for fast access to the given XShapes collection 282 283 <p>This method has to be called before you use exportShape or collectShapeAutoStyles. 284 It is automatically called if you use collectShapesAutoStyles and exportShapes. 285 286 @see collectShapeAutoStyles 287 @see exportShape 288 @see collectShapesAutoStyles 289 @see exportShapes 290 */ 291 void seekShapes( 292 const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xShapes ) throw(); 293 294 void exportAutoStyles(); 295 296 /** sets a new reference to an XMLAnimationExporter. 297 If this is a non NULL reference, the animation information from all shapes given to exportShape() 298 from now on are collected. 299 */ setAnimationsExporter(UniReference<XMLAnimationsExporter> xAnimExport)300 void setAnimationsExporter( UniReference< XMLAnimationsExporter > xAnimExport ) { mxAnimationsExporter = xAnimExport; } 301 302 /** returns the last set XMLAnimationExport */ getAnimationsExporter() const303 UniReference< XMLAnimationsExporter > getAnimationsExporter() const { return mxAnimationsExporter; } 304 305 /// returns the export property mapper for external chaining 306 static SvXMLExportPropertyMapper* CreateShapePropMapper( SvXMLExport& rExport ); 307 enableLayerExport(sal_Bool bEnable=sal_True)308 void enableLayerExport( sal_Bool bEnable = sal_True ) { mbExportLayer = bEnable; } IsLayerExportEnabled() const309 sal_Bool IsLayerExportEnabled() const { return mbExportLayer; } 310 311 // #88546# 312 /** defines if the export should increment the progress bar or not */ enableHandleProgressBar(sal_Bool bEnable=sal_True)313 void enableHandleProgressBar( sal_Bool bEnable = sal_True ) { mbHandleProgressBar = bEnable; } IsHandleProgressBarEnabled() const314 sal_Bool IsHandleProgressBarEnabled() const { return mbHandleProgressBar; } 315 setPresentationStylePrefix(const rtl::OUString & rPrefix)316 void setPresentationStylePrefix( const rtl::OUString& rPrefix ) { msPresentationStylePrefix = rPrefix; } 317 318 /** helper for chart that adds all attributes of a 3d scene element to the export */ 319 void export3DSceneAttributes( const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet ); 320 321 /** helper for chart that exports all lamps from the propertyset */ 322 void export3DLamps( const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet ); 323 324 /** sj: replacing CustomShapes with standard objects that are also supported in OpenOffice.org format */ 325 com::sun::star::uno::Reference < com::sun::star::drawing::XShape > checkForCustomShapeReplacement( 326 const com::sun::star::uno::Reference < com::sun::star::drawing::XShape >& ); 327 328 /** helper to export the style for graphic defaults */ 329 void ExportGraphicDefaults(); 330 331 /** is called before a shape element for the given XShape is exported */ 332 virtual void onExport( const com::sun::star::uno::Reference < com::sun::star::drawing::XShape >& xShape ); 333 334 const rtl::Reference< XMLTableExport >& GetShapeTableExport(); 335 }; 336 337 338 #endif 339