#include "stdafx.h" #include "VMLPictureMapping.h" namespace DocFileFormat { VMLPictureMapping::VMLPictureMapping(ConversionContext* ctx, XmlUtils::CXmlWriter* writer, bool olePreview, IMapping* caller, bool isBulletPicture) : PropertiesMapping(writer) { _ctx = ctx; _olePreview = olePreview; _imageData = NULL; m_nImageId = 0; _caller = caller; _isBulletPicture = isBulletPicture; _imageData = new XMLTools::XMLElement( _T( "v:imagedata" ) ); GUID guid = GUID_NULL; LPOLESTR guidString = NULL; CoCreateGuid (&guid); StringFromCLSID (guid, &guidString); m_ShapeId = std::wstring(guidString); CoTaskMemFree(guidString); } VMLPictureMapping::~VMLPictureMapping() { RELEASEOBJECT (_imageData); } } namespace DocFileFormat { void VMLPictureMapping::Apply( IVisitable* visited ) { PictureDescriptor* pict = static_cast(visited); if (CopyPicture(pict->blipStoreEntry)) { Shape* shape = static_cast(*(pict->shapeContainer->Children.begin())); list options = pict->shapeContainer->ExtractOptions(); //v:shapetype PictureFrameType type; VMLShapeTypeMapping* vmlShapeTypeMapping = new VMLShapeTypeMapping( m_pXmlWriter, this->_isBulletPicture ); type.Convert( vmlShapeTypeMapping ); RELEASEOBJECT( vmlShapeTypeMapping ); //v:shape m_pXmlWriter->WriteNodeBegin( _T( "v:shape" ), true ); m_pXmlWriter->WriteAttribute( _T( "type" ), ( wstring( _T( "#" ) ) + VMLShapeTypeMapping::GenerateTypeId( &type ) ).c_str() ); wstring style; double xScaling = pict->mx / 1000.0; double yScaling = pict->my / 1000.0; TwipsValue width( ( pict->dxaGoal - ( pict->dxaCropLeft + pict->dxaCropRight ) ) * xScaling ); TwipsValue height( ( pict->dyaGoal - ( pict->dyaCropTop + pict->dyaCropBottom ) ) * yScaling ); wstring widthString = FormatUtils::DoubleToWideString( width.ToPoints() ); wstring heightString = FormatUtils::DoubleToWideString( height.ToPoints() ); style = wstring( _T( "width:" ) ) + widthString + wstring( _T( "pt;" ) ) + wstring( _T( "height:" ) ) + heightString + wstring( _T( "pt;" ) ); m_pXmlWriter->WriteAttribute( _T( "style" ), style.c_str() ); m_pXmlWriter->WriteAttribute( _T( "id" ), m_ShapeId.c_str() ); if ( this->_olePreview ) { m_pXmlWriter->WriteAttribute( _T( "o:ole" ), _T( "" ) ); } for ( list::iterator iter = options.begin(); iter != options.end(); iter++ ) { switch ( iter->pid ) { //BORDERS case borderBottomColor: { RGBColor bottomColor( (int)iter->op, RedFirst ); m_pXmlWriter->WriteAttribute( _T( "o:borderbottomcolor" ), ( wstring( _T( "#" ) ) + bottomColor.SixDigitHexCode ).c_str() ); } break; case borderLeftColor: { RGBColor leftColor( (int)iter->op, RedFirst ); m_pXmlWriter->WriteAttribute( _T( "o:borderleftcolor" ), ( wstring( _T( "#" ) ) + leftColor.SixDigitHexCode ).c_str() ); } break; case borderRightColor: { RGBColor rightColor( (int)iter->op, RedFirst ); m_pXmlWriter->WriteAttribute( _T( "o:borderrightcolor" ), ( wstring( _T( "#" ) ) + rightColor.SixDigitHexCode ).c_str() ); } break; case borderTopColor: { RGBColor topColor( (int)iter->op, RedFirst ); m_pXmlWriter->WriteAttribute( _T( "o:bordertopcolor" ), ( wstring( _T( "#" ) ) + topColor.SixDigitHexCode ).c_str() ); } break; //CROPPING case cropFromBottom: { //cast to signed integer int cropBottom = (int)iter->op; appendValueAttribute( this->_imageData, _T( "cropbottom" ), ( FormatUtils::IntToWideString( cropBottom ) + wstring( _T( "f" ) ) ).c_str() ); } break; case cropFromLeft: { //cast to signed integer int cropLeft = (int)iter->op; appendValueAttribute( this->_imageData, _T( "cropleft" ), ( FormatUtils::IntToWideString( cropLeft ) + wstring( _T( "f" ) ) ).c_str() ); } break; case cropFromRight: { //cast to signed integer int cropRight = (int)iter->op; appendValueAttribute( this->_imageData, _T( "cropright" ), ( FormatUtils::IntToWideString( cropRight ) + wstring( _T( "f" ) ) ).c_str() ); } break; case cropFromTop: { //cast to signed integer int cropTop = (int)iter->op; appendValueAttribute( this->_imageData, _T( "croptop" ), ( FormatUtils::IntToWideString( cropTop ) + wstring( _T( "f" ) ) ).c_str() ); } break; } } m_pXmlWriter->WriteNodeEnd( _T( "" ), TRUE, FALSE ); //v:imageData appendValueAttribute( this->_imageData, _T( "r:id" ), ( wstring( _T( "rId" ) ) + FormatUtils::IntToWideString(m_nImageId) ).c_str() ); appendValueAttribute( this->_imageData, _T( "o:title" ) , _T( "" ) ); m_pXmlWriter->WriteString( this->_imageData->GetXMLString().c_str() ); //borders writePictureBorder( _T( "bordertop" ), pict->brcTop ); writePictureBorder( _T( "borderleft" ), pict->brcLeft ); writePictureBorder( _T( "borderbottom" ), pict->brcBottom ); writePictureBorder( _T( "borderright" ), pict->brcRight ); //close v:shape m_pXmlWriter->WriteNodeEnd( _T( "v:shape" ) ); } } std::wstring VMLPictureMapping::GetShapeId () const { return m_ShapeId; } /// Writes a border element void VMLPictureMapping::writePictureBorder( const WCHAR* name, const BorderCode& brc ) { m_pXmlWriter->WriteNodeBegin( ( wstring( _T( "w10:" ) ) + wstring( name ) ).c_str(), true ); m_pXmlWriter->WriteAttribute( _T( "type" ), getBorderType( brc.brcType ).c_str() ); m_pXmlWriter->WriteAttribute( _T( "width" ), FormatUtils::IntToWideString( brc.dptLineWidth ).c_str() ); m_pXmlWriter->WriteNodeEnd( _T( "" ), true ); } /// Copies the picture from the binary stream to the zip archive /// and creates the relationships for the image. bool VMLPictureMapping::CopyPicture (BlipStoreEntry* oBlipEntry) { bool result = false; // write the blip if ((oBlipEntry != NULL) && (oBlipEntry->Blip != NULL)) { switch (oBlipEntry->btWin32) { case Global::msoblipEMF: case Global::msoblipWMF: { //it's a meta image MetafilePictBlip* metaBlip = static_cast(oBlipEntry->Blip); //meta images can be compressed byte* decompressed = NULL; int decompressedSize = 0; decompressedSize = metaBlip->Decompress( &decompressed ); _ctx->_docx->ImagesList.push_back (ImageFileStructure (GetTargetExt(oBlipEntry->btWin32 ), vector( decompressed, ( decompressed + decompressedSize ) ) ) ); RELEASEARRAYOBJECTS( decompressed ); } break; case Global::msoblipJPEG: case Global::msoblipCMYKJPEG: case Global::msoblipPNG: case Global::msoblipTIFF: case Global::msoblipDIB: { //it's a bitmap image BitmapBlip* bitBlip = static_cast(oBlipEntry->Blip); _ctx->_docx->ImagesList.push_back(ImageFileStructure (GetTargetExt(oBlipEntry->btWin32 ), vector( bitBlip->m_pvBits, ( bitBlip->m_pvBits + bitBlip->pvBitsSize ) ) )); } break; default: { result = false; return result; } break; } m_nImageId = _ctx->_docx->RegisterImage (_caller, oBlipEntry->btWin32); result = true; } return result; } } namespace DocFileFormat { std::wstring VMLPictureMapping::GetTargetExt (Global::BlipType nType) { switch (nType) { //case msoblipBMP: // return wstring( _T( ".bmp" ) ); case Global::msoblipEMF: return std::wstring(_T(".emf")); //case msoblipGIF: // return wstring( _T( ".gif" ) ); //case msoblipICON: // return wstring( _T( ".ico" ) ); case Global::msoblipJPEG: case Global::msoblipCMYKJPEG: return std::wstring(_T(".jpg")); //case msoblipPCX: // return wstring( _T( ".pcx" ) ); case Global::msoblipPNG: return std::wstring(_T(".png")); case Global::msoblipTIFF: return std::wstring(_T(".tif")); case Global::msoblipWMF: return std::wstring(_T(".wmf")); default: return std::wstring(_T(".png")); } } std::wstring VMLPictureMapping::GetContentType (Global::BlipType nType) { switch (nType) { //case msoblipBMP: // return wstring( _T( "image/bmp" ) ); case Global::msoblipEMF: return std::wstring(OpenXmlContentTypes::Emf); //case msoblipGIF: // return wstring( _T( "image/gif" ) ); //case msoblipICON: // return wstring( _T( "image/x-icon" ) ); case Global::msoblipJPEG: case Global::msoblipCMYKJPEG: return std::wstring(OpenXmlContentTypes::Jpeg); //case msoblipPCX: // return wstring( _T( "image/pcx" ) ); case Global::msoblipPNG: return std::wstring(OpenXmlContentTypes::Png); case Global::msoblipTIFF: return std::wstring(OpenXmlContentTypes::Tiff); case Global::msoblipWMF: return std::wstring(OpenXmlContentTypes::Wmf); default: return std::wstring(OpenXmlContentTypes::Png); } } }