void ae3d::Font::LoadBMFont( const Texture2D* fontTex, const FileSystem::FileContentsData& metaData ) { if (fontTex != nullptr) { texture = fontTex; } std::stringstream metaStream( std::string( std::begin( metaData.data ), std::end( metaData.data ) ) ); std::string token; // Determines the encoding (text or binary). metaStream >> token; if (token == "info") { LoadBMFontMetaText( metaData ); } else { LoadBMFontMetaBinary( metaData ); } }
HRESULT CCeeGen::emitMetaData(IMetaDataEmit *emitter, CeeSection* section, DWORD offset, BYTE* buffer, unsigned buffLen) { HRESULT hr = S_OK; ReleaseHolder<IStream> metaStream(NULL); IfFailRet((HRESULT)CreateStreamOnHGlobal(NULL, TRUE, &metaStream)); if (! m_fTokenMapSupported) { IUnknown *pMapTokenIface; IfFailGoto(getMapTokenIface(&pMapTokenIface, emitter), Exit); // Set a callback for token remap and save the tokens which change. IfFailGoto(emitter->SetHandler(pMapTokenIface), Exit); } // generate the metadata IfFailGoto(emitter->SaveToStream(metaStream, 0), Exit); // get size of stream and get sufficient storage for it if (section == 0) { section = &getMetaSection(); STATSTG statStg; IfFailGoto((HRESULT)(metaStream->Stat(&statStg, STATFLAG_NONAME)), Exit); buffLen = statStg.cbSize.u.LowPart; if(m_objSwitch) { CeeSection* pSect; DWORD flags = IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE | IMAGE_SCN_ALIGN_1BYTES; // 0x00100A00 IfFailGoto(getSectionCreate(".cormeta",flags,&pSect,&m_metaIdx), Exit); } buffer = (BYTE *)section->getBlock(buffLen, sizeof(DWORD)); IfNullGoto(buffer, Exit); offset = getMetaSection().dataLen() - buffLen; } else { _ASSERTE(buffer[buffLen-1] || true); // Dereference 'buffer' _ASSERTE(section->computeOffset(PCHAR(buffer)) == offset); } // reset seek pointer and read from stream { LARGE_INTEGER disp = { {0, 0} }; IfFailGoto((HRESULT)metaStream->Seek(disp, STREAM_SEEK_SET, NULL), Exit); } ULONG metaDataLen; IfFailGoto((HRESULT)metaStream->Read(buffer, buffLen+1, &metaDataLen), Exit); _ASSERTE(metaDataLen <= buffLen); // Set meta virtual address to offset of metadata within .meta, and // and add a reloc for this offset, which will get turned // into an rva when the pewriter writes out the file. m_corHeader->MetaData.VirtualAddress = VAL32(offset); getCorHeaderSection().addSectReloc(m_corHeaderOffset + offsetof(IMAGE_COR20_HEADER, MetaData), *section, srRelocAbsolute); m_corHeader->MetaData.Size = VAL32(metaDataLen); Exit: if (! m_fTokenMapSupported) { // Remove the handler that we set hr = emitter->SetHandler(NULL); } #ifdef _DEBUG if (FAILED(hr) && hr != E_OUTOFMEMORY) _ASSERTE(!"Unexpected Failure"); #endif return hr; }
void ae3d::Font::LoadBMFontMetaText( const FileSystem::FileContentsData& metaData ) { std::stringstream metaStream( std::string( metaData.data.begin(), metaData.data.end() ) ); std::string line; std::getline( metaStream, line ); std::string token; // First line (info) std::stringstream infoStream( line ); while (!infoStream.eof()) { infoStream >> token; if (token.find( "padding" ) != std::string::npos) { const char a[ 2 ] = { token[ 8 ], 0 }; const char b[ 2 ] = { token[ 10 ], 0 }; const char c[ 2 ] = { token[ 12 ], 0 }; const char d[ 2 ] = { token[ 14 ], 0 }; padding[ 0 ] = std::atoi( a ); padding[ 1 ] = std::atoi( b ); padding[ 2 ] = std::atoi( c ); padding[ 3 ] = std::atoi( d ); } else if (token.find( "spacing" ) != std::string::npos) { const char a[ 2 ] = { token[ 8 ], 0 }; const char b[ 2 ] = { token[ 10 ], 0 }; spacing[ 0 ] = std::atoi( a ); spacing[ 1 ] = std::atoi( b ); } } std::getline( metaStream, line ); // Second line (common) std::stringstream commonStream( line ); while (!commonStream.eof()) { commonStream >> token; if (token.find( "lineHeight" ) != std::string::npos) { const char a[ 3 ] = { token[ 11 ], token[ 12 ], 0 }; lineHeight = std::atoi( a ); } else if (token.find( "base" ) != std::string::npos) { const char a[ 3 ] = { token[ 5 ], token[ 6 ], 0 }; base = std::atoi( a ); } } // Third line (page) std::getline( metaStream, line ); // Fourth line (chars) std::getline( metaStream, line ); // Character tags. while (!metaStream.eof()) { std::getline( metaStream, line ); std::stringstream charStream( line ); charStream.seekg( line.find( "id=" ) + 3 ); int id; charStream >> id; if (id > 255) { continue; } charStream.seekg( line.find( "x=" ) + 2 ); charStream >> chars[ id ].x; charStream.seekg( line.find( "y=" ) + 2 ); charStream >> chars[ id ].y; charStream.seekg( line.find( "width=" ) + 6 ); charStream >> chars[ id ].width; charStream.seekg( line.find( "height=" ) + 7 ); charStream >> chars[ id ].height; charStream.seekg( line.find( "xoffset=" ) + 8 ); charStream >> chars[ id ].xOffset; charStream.seekg( line.find( "yoffset=" ) + 8 ); charStream >> chars[ id ].yOffset; charStream.seekg( line.find( "xadvance=" ) + 9 ); charStream >> chars[ id ].xAdvance; } }
void ae3d::Texture2D::LoadFromAtlas( const FileSystem::FileContentsData& atlasTextureData, const FileSystem::FileContentsData& atlasMetaData, const char* textureName, TextureWrap aWrap, TextureFilter aFilter, float aAnisotropy ) { Load( atlasTextureData, aWrap, aFilter, mipmaps, aAnisotropy ); const std::string metaStr = std::string( std::begin( atlasMetaData.data ), std::end( atlasMetaData.data ) ); std::stringstream metaStream( metaStr ); if (atlasMetaData.path.find( ".xml" ) == std::string::npos && atlasMetaData.path.find( ".XML" ) == std::string::npos) { System::Print( "Atlas meta data path %s could not be opened!", atlasMetaData.path.c_str() ); return; } std::string line; while (std::getline( metaStream, line )) { if (line.find( "<Image Name" ) == std::string::npos) { continue; } std::vector< std::string > tokens; Tokenize( line, tokens, "\"" ); bool found = false; for (std::size_t t = 0; t < tokens.size(); ++t) { if (tokens[ t ].find( "Name" ) != std::string::npos) { if (tokens[ t + 1 ] == textureName) { found = true; } } if (!found) { continue; } if (tokens[ t ].find( "XPos" ) != std::string::npos) { scaleOffset.z = std::stoi( tokens[ t + 1 ] ) / static_cast<float>(width); } else if (tokens[ t ].find( "YPos" ) != std::string::npos) { scaleOffset.w = std::stoi( tokens[ t + 1 ] ) / static_cast<float>(height); } else if (tokens[ t ].find( "Width" ) != std::string::npos) { const int w = std::stoi( tokens[ t + 1 ] ); scaleOffset.x = 1.0f / (static_cast<float>(width) / static_cast<float>(w)); width = w; } else if (tokens[ t ].find( "Height" ) != std::string::npos) { const int h = std::stoi( tokens[ t + 1 ] ); scaleOffset.y = 1.0f / (static_cast<float>(height) / static_cast<float>(h)); height = h; } } if (found) { return; } } }