2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://floralicense.org/license/
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an AS IS BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 #include "resource-loader.h"
21 #include <boost/thread.hpp>
28 #include <dali/integration-api/bitmap.h>
29 #include <dali/integration-api/debug.h>
30 #include <dali/integration-api/resource-cache.h>
31 #include <dali/public-api/common/dali-common.h>
32 #include <dali/public-api/math/vector2.h>
33 #include "resource-requester-base.h"
34 #include "resource-bitmap-requester.h"
35 #include "resource-model-requester.h"
36 #include "resource-shader-requester.h"
37 #include "resource-text-requester.h"
38 #include "debug/resource-loader-debug.h"
39 #include "loader-font.h"
40 #include "../interfaces/font-controller.h"
41 #include "../interfaces/data-cache.h"
45 * A macro to expand an argument to a compile time constant string literal.
46 * Wrapping the stringify in an outer macro, means that any macro passed as
47 * "x" will be expanded before being turned into a string.
48 * Use this for example to turn the current line number into a string:
49 * puts("The current line number is " DALI_TO_STRING(__LINE__) ".");
51 #define DALI_TO_STRING_INNER(x) #x
52 #define DALI_TO_STRING(x) DALI_TO_STRING_INNER(x)
54 using namespace Dali::Integration;
56 using boost::unique_lock;
57 using boost::scoped_ptr;
68 const char * const DALI_USER_FONT_CACHE_PATH( DALI_USER_FONT_CACHE_DIR );
69 const unsigned int MAX_NUMBER_CHARS_TO_CACHE( 60000 ); ///< support up to 60,000 glyphs
70 const unsigned int DISTANCE_FIELD_SIZE = 64; // doesn't need to be power of two (the atlas may for performance)
71 const unsigned int DISTANCE_FIELD_PADDING = 30; // Number of pixels of padding around the source FreeType bitmap
72 const unsigned int HIGH_QUALITY_PIXEL_SIZE = 200; // Pixel size sent to FreeType2 FT_Set_Char_Size() for high quality glyphs
73 const float ONE_OVER_64 = 1.0f/64.0f;
76 // For DEBUG_ENABLED profiling of distance field glyph generation
77 double GetTimeMicroseconds()
80 clock_gettime(CLOCK_MONOTONIC, &time);
81 double seconds = time.tv_sec;
82 seconds += 1e-3 * time.tv_nsec;
87 } // unnamed namespace
90 struct ResourceLoader::ResourceLoaderImpl
92 typedef std::pair<ResourceId, ResourceRequest> RequestStorePair;
93 typedef std::map<ResourceId, ResourceRequest> RequestStore;
94 typedef RequestStore::iterator RequestStoreIter;
96 typedef std::queue<LoadedResource> LoadedQueue;
97 typedef std::queue<SavedResource> SavedQueue;
98 typedef std::queue<FailedResource> FailedQueue;
100 typedef std::pair<ResourceTypeId, ResourceRequesterBase*> RequestHandlerPair;
101 typedef std::map<ResourceTypeId, ResourceRequesterBase*> RequestHandlers;
102 typedef RequestHandlers::iterator RequestHandlersIter;
104 boost::mutex mQueueMutex; ///< used to synchronize access to mLoadedQueue, mSavedQueue and mFailedQueue
105 LoadedQueue mPartiallyLoadedQueue; ///< Partially complete load requests notifications are stored here until fetched by core
106 LoadedQueue mLoadedQueue; ///< Completed load requests notifications are stored here until fetched by core
107 SavedQueue mSavedQueue; ///< Completed save request notifications are stored here until fetched by core
108 FailedQueue mFailedLoads; ///< Failed load request notifications are stored here until fetched by core
109 FailedQueue mFailedSaves; ///< Failed save request notifications are stored here until fetched by core
111 Dali::Platform::FontController* mFontController; ///< Interface for accessing font information
113 RequestHandlers mRequestHandlers;
114 RequestStore mStoredRequests; ///< Used to store load requests until loading is completed
116 ResourceLoaderImpl( ResourceLoader* loader )
118 mFontController = Dali::Platform::FontController::New();
120 mRequestHandlers.insert(std::make_pair(ResourceBitmap, new ResourceBitmapRequester(*loader)));
121 mRequestHandlers.insert(std::make_pair(ResourceShader, new ResourceShaderRequester(*loader)));
122 mRequestHandlers.insert(std::make_pair(ResourceModel, new ResourceModelRequester(*loader)));
123 mRequestHandlers.insert(std::make_pair(ResourceText, new ResourceTextRequester(*loader)));
126 ~ResourceLoaderImpl()
128 // Delete resource handlers
129 for( RequestHandlersIter it = mRequestHandlers.begin(); it != mRequestHandlers.end(); ++it )
131 ResourceRequesterBase* requestBase = it->second;
135 delete mFontController;
140 // Pause all the request handlers:
141 for( RequestHandlersIter it = mRequestHandlers.begin(), end = mRequestHandlers.end(); it != end; ++it )
143 ResourceRequesterBase * const requester = it->second;
153 // Wake up all the request handlers:
154 for( RequestHandlersIter it = mRequestHandlers.begin(), end = mRequestHandlers.end(); it != end; ++it )
156 ResourceRequesterBase * const requester = it->second;
164 ResourceRequesterBase* GetRequester(ResourceTypeId typeId)
166 ResourceRequesterBase* requestHandler = NULL;
167 RequestHandlersIter iter = mRequestHandlers.find(typeId);
168 if(iter != mRequestHandlers.end())
170 requestHandler = iter->second;
172 DALI_ASSERT_DEBUG(requestHandler && "All resource types should have a requester defined for them.");
173 return requestHandler;
176 void LoadResource(const ResourceRequest& request)
178 // Store resource request for partial loaders. Will get cleaned up after load complete has finished
179 StoreRequest(request);
181 ResourceRequesterBase* requester = GetRequester(request.GetType()->id);
184 ResourceRequest* storedRequest = GetRequest(request.GetId());
185 if( storedRequest != NULL )
187 requester->LoadResource(*storedRequest); // Pass in stored request
192 DALI_LOG_ERROR( "Unknown resource type (%u) with path \"%s\" in load request.\n", request.GetType()->id, request.GetPath().c_str() );
193 DALI_ASSERT_DEBUG( 0 == "Unknown resource type in load request at " __FILE__ ", line " DALI_TO_STRING(__LINE__) ".\n" );
197 void SaveResource(const ResourceRequest& request)
199 ResourceRequesterBase* requester = GetRequester( request.GetType()->id );
202 requester->SaveResource( request );
206 void CancelLoad(ResourceId id, ResourceTypeId typeId)
208 ResourceRequesterBase* requester = GetRequester(typeId);
211 requester->CancelLoad( id, typeId );
216 LoadStatus LoadFurtherResources( LoadedResource partialResource )
218 LoadStatus loadStatus = RESOURCE_LOADING;
219 RequestStoreIter iter = mStoredRequests.find(partialResource.id);
221 if( mStoredRequests.end() != iter ) // else cancelled. Ignore response
223 ResourceRequest& request = iter->second;
224 ResourceRequesterBase* requester = GetRequester(request.GetType()->id);
227 loadStatus = requester->LoadFurtherResources( request, partialResource );
230 DALI_LOG_INFO(gLoaderFilter, Debug::General, "ResourceLoader::LoadFurtherResources( ID:%u complete: %s)\n", request.GetId(), loadStatus==RESOURCE_LOADING?"Loading":loadStatus==RESOURCE_PARTIALLY_LOADED?"PARTIAL":"COMPLETE" );
233 if( loadStatus == RESOURCE_COMPLETELY_LOADED )
235 ClearRequest( partialResource.id );
243 // TODO - not used - remove?
247 void GetResources(ResourceCache& cache)
249 // Fill the resource cache
251 unique_lock<mutex> lock(mQueueMutex);
253 // iterate through the partially loaded resources
254 while (!mPartiallyLoadedQueue.empty())
256 LoadedResource loaded( mPartiallyLoadedQueue.front() );
257 mPartiallyLoadedQueue.pop();
258 LoadStatus loadStatus = LoadFurtherResources( loaded );
259 cache.LoadResponse( loaded.id, loaded.type, loaded.resource, loadStatus );
262 // iterate through the successfully loaded resources
263 while (!mLoadedQueue.empty())
265 LoadedResource loaded( mLoadedQueue.front() );
267 ClearRequest( loaded.id );
268 cache.LoadResponse( loaded.id, loaded.type, loaded.resource, RESOURCE_COMPLETELY_LOADED );
271 // iterate through the successfully saved resources
272 while (!mSavedQueue.empty())
274 SavedResource saved(mSavedQueue.front());
276 cache.SaveComplete(saved.id, saved.type);
279 // iterate through the resources which failed to load
280 while (!mFailedLoads.empty())
282 FailedResource failed(mFailedLoads.front());
284 ClearRequest(failed.id);
285 cache.LoadFailed(failed.id, failed.failureType);
288 // iterate through the resources which failed to save
289 while (!mFailedSaves.empty())
291 FailedResource failed(mFailedSaves.front());
293 cache.SaveFailed(failed.id, failed.failureType);
297 void GetClosestImageSize( const std::string& filename,
298 const ImageAttributes& attributes,
299 Vector2& closestSize )
301 ResourceRequesterBase* requester = GetRequester(ResourceBitmap);
302 ResourceBitmapRequester* bitmapRequester = dynamic_cast<ResourceBitmapRequester*>(requester);
303 if( bitmapRequester != NULL )
305 bitmapRequester->GetClosestImageSize( filename, attributes, closestSize );
309 void GetClosestImageSize( ResourcePointer resourceBuffer,
310 const ImageAttributes& attributes,
311 Vector2& closestSize )
313 ResourceRequesterBase* requester = GetRequester(ResourceBitmap);
314 ResourceBitmapRequester* bitmapRequester = dynamic_cast<ResourceBitmapRequester*>(requester);
315 if( bitmapRequester != NULL )
317 bitmapRequester->GetClosestImageSize( resourceBuffer, attributes, closestSize );
321 void AddPartiallyLoadedResource( LoadedResource& resource)
323 // Lock the LoadedQueue to store the loaded resource
324 unique_lock<mutex> lock(mQueueMutex);
326 mPartiallyLoadedQueue.push( resource );
329 void AddLoadedResource(LoadedResource& resource)
331 // Lock the LoadedQueue to store the loaded resource
332 unique_lock<mutex> lock(mQueueMutex);
334 mLoadedQueue.push( resource );
337 void AddSavedResource(SavedResource& resource)
339 // Lock the SavedQueue to store the loaded resource
340 unique_lock<mutex> lock(mQueueMutex);
342 mSavedQueue.push(resource);
345 void AddFailedLoad(FailedResource& resource)
347 // Lock the FailedQueue to store the failed resource information
348 unique_lock<mutex> lock(mQueueMutex);
350 mFailedLoads.push(resource);
353 void AddFailedSave(FailedResource& resource)
355 // Lock the FailedQueue to store the failed resource information
356 unique_lock<mutex> lock(mQueueMutex);
358 mFailedSaves.push(resource);
361 void StoreRequest( const ResourceRequest& request )
363 DALI_LOG_INFO(gLoaderFilter, Debug::Verbose, "ResourceLoader: StoreRequest(id:%u)\n", request.GetId());
364 mStoredRequests.insert( RequestStorePair( request.GetId(), request ) ); // copy request as value type
367 ResourceRequest* GetRequest( ResourceId id )
369 ResourceRequest* found(NULL);
370 DALI_LOG_INFO(gLoaderFilter, Debug::Verbose, "ResourceLoader: GetRequest(id:%u)\n", id);
371 RequestStoreIter iter = mStoredRequests.find( id );
372 if( mStoredRequests.end() != iter )
374 found = &iter->second;
379 void ClearRequest( ResourceId resourceId )
381 DALI_LOG_INFO(gLoaderFilter, Debug::Verbose, "ResourceLoader: ClearRequest(id:%u)\n", resourceId);
382 RequestStoreIter iter = mStoredRequests.find( resourceId );
383 if( mStoredRequests.end() != iter ) // Can't assert here - cancel load may cross with load failed
385 mStoredRequests.erase( iter );
390 /********************************************************************************/
391 /**************************** RESOURCE LOADER METHODS ************************/
392 /********************************************************************************/
393 ResourceLoader::ResourceLoader()
394 : mTerminateThread(0)
396 mImpl = new ResourceLoaderImpl( this );
399 ResourceLoader::~ResourceLoader()
401 // Flag that the ResourceLoader is exiting
402 (void)__sync_or_and_fetch( &mTerminateThread, -1 );
407 void ResourceLoader::Pause()
412 void ResourceLoader::Resume()
417 bool ResourceLoader::IsTerminating()
419 return __sync_fetch_and_or( &mTerminateThread, 0 );
422 void ResourceLoader::GetResources(ResourceCache& cache)
424 mImpl->GetResources( cache );
427 /********************************************************************************/
428 /************************** CALLED FROM LOADER THREADS **********************/
429 /********************************************************************************/
431 void ResourceLoader::AddPartiallyLoadedResource( LoadedResource& resource)
433 mImpl->AddPartiallyLoadedResource( resource );
436 void ResourceLoader::AddLoadedResource(LoadedResource& resource)
438 mImpl->AddLoadedResource( resource );
441 void ResourceLoader::AddSavedResource(SavedResource& resource)
443 mImpl->AddSavedResource( resource );
446 void ResourceLoader::AddFailedLoad(FailedResource& resource)
448 mImpl->AddFailedLoad( resource );
451 void ResourceLoader::AddFailedSave(FailedResource& resource)
453 mImpl->AddFailedSave( resource );
456 /********************************************************************************/
457 /********************* CALLED FROM PLATFORM ABSTRACTION **********************/
458 /********************************************************************************/
460 void ResourceLoader::LoadResource(const ResourceRequest& request)
462 mImpl->LoadResource(request);
465 void ResourceLoader::SaveResource(const ResourceRequest& request)
467 mImpl->SaveResource(request);
470 void ResourceLoader::CancelLoad(ResourceId id, ResourceTypeId typeId)
472 mImpl->CancelLoad(id, typeId);
475 bool ResourceLoader::IsLoading()
477 return mImpl->IsLoading();
480 void ResourceLoader::GetClosestImageSize( const std::string& filename,
481 const ImageAttributes& attributes,
482 Vector2& closestSize )
484 mImpl->GetClosestImageSize( filename, attributes, closestSize );
487 void ResourceLoader::GetClosestImageSize( ResourcePointer resourceBuffer,
488 const ImageAttributes& attributes,
489 Vector2& closestSize )
491 mImpl->GetClosestImageSize( resourceBuffer, attributes, closestSize );
495 std::string ResourceLoader::GetFontFamilyForChars(const TextArray& charsRequested)
497 return mImpl->mFontController->GetFontFamilyForChars( charsRequested ).first;
500 bool ResourceLoader::AllGlyphsSupported(const std::string &fontFamily, const std::string &fontStyle, const TextArray& charsRequested)
502 return mImpl->mFontController->AllGlyphsSupported( Platform::FontController::StyledFontFamily( fontFamily, fontStyle ), charsRequested);
506 bool ResourceLoader::ValidateFontFamilyName(const std::string& fontFamily, const std::string& fontStyle, bool& isDefaultSystemFont, std::string& closestFontFamilyMatch, std::string& closestFontStyleMatch)
508 Platform::FontController::StyledFontFamily closestMatch;
510 bool result = mImpl->mFontController->ValidateFontFamilyName( Platform::FontController::StyledFontFamily( fontFamily, fontStyle ), isDefaultSystemFont, closestMatch);
512 closestFontFamilyMatch = closestMatch.first;
513 closestFontStyleMatch = closestMatch.second;
518 const PixelSize ResourceLoader::GetFontLineHeightFromCapsHeight(const std::string fontFamily, const std::string& fontStyle, const CapsHeight& capsHeight, FT_Library freeType)
522 if (!fontFamily.empty())
524 std::string fontFileName = GetFontPath( fontFamily, fontStyle );
525 SlpFace* slpFace = LoadFontFace(fontFileName, PixelSize(capsHeight), freeType);
529 const float scale = static_cast<float>(capsHeight.value) / ((slpFace->face->ascender / 64.0f) * 0.95f);
531 result.value = static_cast<unsigned int>(roundf(scale * (slpFace->face->height / 64.0f)));
541 std::vector<std::string> ResourceLoader::GetFontList( Dali::Integration::PlatformAbstraction::FontListMode mode )
543 std::vector<std::string> result;
544 std::set<std::string> uniqueFontNames;
546 // VCC TODO: A GetStyles() method which returns a list of styles for a given font family is needed.
548 Platform::FontController::FontList fontList;
549 Platform::FontController::FontListMode listMode;
553 case Dali::Integration::PlatformAbstraction::LIST_ALL_FONTS:
555 listMode = Platform::FontController::LIST_ALL_FONTS;
558 case Dali::Integration::PlatformAbstraction::LIST_SYSTEM_FONTS:
560 listMode = Platform::FontController::LIST_SYSTEM_FONTS;
563 case Dali::Integration::PlatformAbstraction::LIST_APPLICATION_FONTS:
565 listMode = Platform::FontController::LIST_APPLICATION_FONTS;
570 DALI_ASSERT_DEBUG(0 && "invalid mode");
575 fontList = mImpl->mFontController->GetFontList( listMode );
577 for( Platform::FontController::FontList::const_iterator it = fontList.begin(), endIt = fontList.end(); it != endIt; ++it )
579 uniqueFontNames.insert(it->first);
582 // copy into a vector
583 std::copy(uniqueFontNames.begin(), uniqueFontNames.end(), std::back_inserter(result));
590 * Note, called from both platform abstraction & from text loader threads
592 GlyphSet* ResourceLoader::GetGlyphData (const TextResourceType& textRequest,
594 const std::string& fontFamily,
597 GlyphSet* glyphSet = NULL;
599 size_t fontHash = textRequest.mFontHash;
601 DALI_LOG_INFO(gLoaderFilter, Debug::Verbose, "LoadGlyphSet - requested string is %d characters long\n", textRequest.mCharacterList.size());
603 // path holds the font name
604 if( !fontFamily.empty() )
606 std::string fontFileName = GetFontPath( fontFamily, textRequest.mStyle );
608 const bool highQuality(textRequest.mQuality == TextResourceType::TextQualityHigh);
609 const unsigned int glyphQuality( highQuality ? GlyphMetrics::HIGH_QUALITY : GlyphMetrics::LOW_QUALITY );
611 SlpFace* slpFace = LoadFontFace( fontFileName, PixelSize( HIGH_QUALITY_PIXEL_SIZE), freeType );
614 glyphSet = new GlyphSet();
615 glyphSet->mFontHash = fontHash;
616 glyphSet->SetAtlasResourceId( textRequest.mTextureAtlasId );
618 for( TextResourceType::CharacterList::const_iterator it = textRequest.mCharacterList.begin(), endIt = textRequest.mCharacterList.end(); it != endIt; ++it )
620 uint32_t charCode( it->character );
622 if (!glyphSet->HasCharacter(charCode)) // ignore duplicate glyphs in the request
625 // DEBUG_ENABLED profiling of distance field glyph generation
629 then = GetTimeMicroseconds();
632 scoped_ptr< GlyphSet::Character > character( GetCharacter(slpFace->face, charCode,
633 DISTANCE_FIELD_SIZE, DISTANCE_FIELD_PADDING, textRequest.mMaxGlyphSize,
634 getBitmap, highQuality ) );
637 // DEBUG_ENABLED profiling of distance field glyph generation
640 double now( GetTimeMicroseconds() );
642 DALI_LOG_INFO( gLoaderFilter, Log::Verbose, "Generating (%c) in %s quality took %.3f ms\n", charCode, highQuality ? "high" : "low", 1e-3 * ( now - then ) );
647 GlyphSet::Character& glyphCharacter( *character.get() );
649 glyphCharacter.second.quality = glyphQuality;
650 glyphCharacter.second.xPosition = it->xPosition;
651 glyphCharacter.second.yPosition = it->yPosition;
652 // copy character to GlyphSet
653 glyphSet->AddCharacter( glyphCharacter );
665 GlyphSet* ResourceLoader::GetCachedGlyphData(const TextResourceType& textRequest, const std::string& fontFamily)
667 GlyphSet* glyphSet( new GlyphSet() );
668 glyphSet->mFontHash = textRequest.mFontHash;
669 glyphSet->SetAtlasResourceId(textRequest.mTextureAtlasId);
671 std::string cachePath(DALI_USER_FONT_CACHE_PATH);
672 cachePath.append(fontFamily + "-" + textRequest.mStyle);
673 std::replace(cachePath.begin(), cachePath.end(), ' ', '-');
675 DALI_LOG_INFO(gLoaderFilter, Debug::Verbose, "ResourceLoader::GetCachedGlyphData() - cachefile: %s\n", cachePath.c_str() );
677 Platform::DataCache* dataCache = Platform::DataCache::New( Platform::DataCache::READ_ONLY,
678 Platform::DataCache::RUN_LENGTH_ENCODING,
680 DISTANCE_FIELD_SIZE * DISTANCE_FIELD_SIZE,
681 MAX_NUMBER_CHARS_TO_CACHE);
683 Platform::DataCache::KeyVector keyVector;
684 Platform::DataCache::DataVector dataVector;
686 const TextResourceType::CharacterList& requestedCharacters = textRequest.mCharacterList;
687 for( std::size_t i=0, length = requestedCharacters.size(); i < length; ++i )
689 keyVector.push_back( requestedCharacters[i].character );
692 // load the glyphs from file
693 dataCache->Find( keyVector, dataVector );
695 // for each glyph found, add to the glyph set
696 for( std::size_t n = 0, arraySize = keyVector.size(); n < arraySize ; n++ )
698 Platform::DataCache::Data& data( dataVector[n]);
702 GlyphMetrics glyphMetrics;
703 glyphMetrics.code = keyVector[ n ];
704 glyphMetrics.quality = GlyphMetrics::HIGH_QUALITY;
705 glyphMetrics.xPosition = requestedCharacters[n].xPosition;
706 glyphMetrics.yPosition = requestedCharacters[n].yPosition;
708 // create a new bitmap, and copy in the data
709 BitmapPtr bitmapData ( Integration::Bitmap::New(Bitmap::BITMAP_2D_PACKED_PIXELS, true) );
710 DALI_ASSERT_ALWAYS( data.length == DISTANCE_FIELD_SIZE * DISTANCE_FIELD_SIZE );
713 bitmapData->GetPackedPixelsProfile()->AssignBuffer( Pixel::A8, data.data, DISTANCE_FIELD_SIZE * DISTANCE_FIELD_SIZE, DISTANCE_FIELD_SIZE, DISTANCE_FIELD_SIZE );
717 // add to the glyphset
718 glyphSet->AddCharacter( bitmapData, glyphMetrics );
721 DALI_LOG_INFO( gLoaderFilter, Debug::Verbose, "ResourceLoader::GetCachedGlyphData() - requestedGlyphs:%u, cachedGlyphs:%u\n",
722 requestedCharacters.size(), glyphSet->GetCharacterList().size() );
729 void ResourceLoader::GetGlobalMetrics( FT_Library freeType,
730 const std::string& fontFamily,
731 const std::string& fontStyle,
732 GlobalMetrics& globalMetrics )
734 // path holds the font name
735 if( !fontFamily.empty() )
737 std::string fontFileName = GetFontPath( fontFamily, fontStyle );
739 SlpFace* slpFace = LoadFontFace( fontFileName, PixelSize( HIGH_QUALITY_PIXEL_SIZE), freeType );
742 // scale factor for unit scaled glyphs
743 const float xScale = 1.0f / (slpFace->face->size->metrics.x_scale / 65536.0f);
744 const float yScale = 1.0f / (slpFace->face->size->metrics.y_scale / 65536.0f);
746 globalMetrics.lineHeight = slpFace->face->height * ONE_OVER_64;
747 globalMetrics.ascender = slpFace->face->ascender * ONE_OVER_64;
748 globalMetrics.unitsPerEM = slpFace->face->units_per_EM * ONE_OVER_64;
750 globalMetrics.underlinePosition = -4.f;
751 globalMetrics.underlineThickness = 5.f * yScale;
752 if( 1.f > globalMetrics.underlineThickness )
754 globalMetrics.underlineThickness = 1.f;
756 globalMetrics.maxWidth = DISTANCE_FIELD_SIZE * xScale;
757 globalMetrics.maxHeight = DISTANCE_FIELD_SIZE * yScale;
758 globalMetrics.padAdjustX = DISTANCE_FIELD_PADDING * xScale;
759 globalMetrics.padAdjustY = DISTANCE_FIELD_PADDING * yScale;
766 void ResourceLoader::SetDpi(unsigned int dpiHor, unsigned int dpiVer)
771 bool ResourceLoader::LoadFile( const std::string& filename, std::vector< unsigned char >& buffer ) const
773 DALI_LOG_TRACE_METHOD(gLoaderFilter);
775 DALI_ASSERT_DEBUG( 0 != filename.length());
780 buf.open(filename.c_str(), std::ios::in | std::ios::binary);
783 std::istream stream(&buf);
785 // determine data length
786 stream.seekg(0, std::ios_base::end);
787 unsigned int length = static_cast<unsigned int>( stream.tellg() );
788 stream.seekg(0, std::ios_base::beg);
791 buffer.resize(length);
792 // read data into buffer
793 stream.read(reinterpret_cast<char*>(buffer.data()), length);
795 DALI_LOG_INFO(gLoaderFilter, Debug::Verbose, "ResourceLoader::LoadFile(%s) - loaded %d bytes\n", filename.c_str(), length);
801 DALI_LOG_INFO(gLoaderFilter, Debug::Verbose, "ResourceLoader::LoadFile(%s) - failed to load\n", filename.c_str());
808 std::string ResourceLoader::LoadFile(const std::string& filename) const
810 DALI_LOG_TRACE_METHOD(gLoaderFilter);
812 DALI_ASSERT_DEBUG( 0 != filename.length());
814 std::string contents;
817 buf.open(filename.c_str(), std::ios::in);
820 std::istream stream(&buf);
822 // determine data length
823 stream.seekg(0, std::ios_base::end);
824 unsigned int length = static_cast<unsigned int>( stream.tellg() );
825 stream.seekg(0, std::ios_base::beg);
828 contents.resize(length);
829 // read data into buffer
830 stream.read(&contents[0], length);
832 DALI_LOG_INFO(gLoaderFilter, Debug::Verbose, "ResourceLoader::LoadFile(%s) - loaded %d bytes\n", filename.c_str(), length);
836 DALI_LOG_INFO(gLoaderFilter, Debug::Verbose, "ResourceLoader::LoadFile(%s) - failed to load\n", filename.c_str());
842 bool ResourceLoader::SaveFile(const std::string& filename, std::vector< unsigned char >& buffer)
844 DALI_LOG_TRACE_METHOD(gLoaderFilter);
846 DALI_ASSERT_DEBUG( 0 != filename.length());
851 buf.open(filename.c_str(), std::ios::out | std::ios_base::trunc | std::ios::binary);
854 std::ostream stream(&buf);
856 // determine size of buffer
857 int length = static_cast<int>(buffer.size());
859 // write contents of buffer to the file
860 stream.write(reinterpret_cast<char*>(buffer.data()), length);
864 DALI_LOG_INFO(gLoaderFilter, Debug::Verbose, "ResourceLoader::SaveFile(%s) - wrote %d bytes\n", filename.c_str(), length);
869 #if defined(DEBUG_BUILD)
872 DALI_LOG_INFO(gLoaderFilter, Debug::Verbose, "ResourceLoader::SaveFile(%s) - failed to load\n", filename.c_str());
879 void ResourceLoader::SetDefaultFontFamily( const std::string& fontFamily, const std::string& fontStyle )
881 mImpl->mFontController->SetDefaultFontFamily( Platform::FontController::StyledFontFamily( fontFamily, fontStyle ) );
884 std::string ResourceLoader::GetFontPath(const std::string& fontFamily, const std::string& fontStyle)
886 return mImpl->mFontController->GetFontPath(std::make_pair(fontFamily,fontStyle));
889 } // namespace SlpPlatform