2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FApp_AppResourceBitmapUtil.cpp
20 * @brief This is the implementation for the _AppResourceBitmapUtil class.
23 #include <unique_ptr.h>
25 #include <FAppPkgPackageInfo.h>
26 #include <FBaseSysLog.h>
27 #include <FBaseByteBuffer.h>
28 #include <FMediaImageTypes.h>
29 #include <FMedia_ImageDecoder.h>
30 #include <FSys_SystemInfoImpl.h>
31 #include <FUi_ControlManager.h>
32 #include <FUi_CoordinateSystemUtils.h>
34 #include "FApp_AppInfo.h"
35 #include "FAppPkg_PackageInfoImpl.h"
36 #include "FApp_AppResourceBitmapUtil.h"
38 using namespace Tizen::App::Package;
39 using namespace Tizen::Base;
40 using namespace Tizen::Graphics;
41 using namespace Tizen::Io;
42 using namespace Tizen::Media;
43 using namespace Tizen::Ui;
48 ConvertBitmapPixelFormatToMediaPixelFormat(BitmapPixelFormat format)
50 MediaPixelFormat out = MEDIA_PIXEL_FORMAT_NONE;
53 case BITMAP_PIXEL_FORMAT_RGB565:
54 out = MEDIA_PIXEL_FORMAT_RGB565LE;
56 case BITMAP_PIXEL_FORMAT_ARGB8888:
57 out = MEDIA_PIXEL_FORMAT_BGRA8888;
59 case BITMAP_PIXEL_FORMAT_R8G8B8A8:
60 out = MEDIA_PIXEL_FORMAT_RGBA8888;
66 }} // unnamed namespace
68 namespace Tizen { namespace Graphics
71 _CreateCoordinateTransformer(_ICoordinateSystemTransformer*& pTransformer, int srcResolution, _BaseScreenSize srcBaseScreenSize, Dimension destResolution, _BaseScreenSize destBaseScreenSize);
74 namespace Tizen { namespace App
77 _AppResourceBitmapUtil::_AppResourceBitmapUtil(void)
78 : __physicalResolutionDim(0, 0)
79 , __physicalBaseScreenSize(BASE_SCREEN_SIZE_DEFAULT)
80 , __resolutionDirectories(L"")
81 , __sortedDensityDirectories()
83 for (int i = 0; i < DENSITY_MAX; i++)
85 __sortedDensity[i] = DENSITY_NONE;
87 __physicalResolutionDim = _CoordinateSystem::GetInstance()->GetPhysicalResolutionDim();
88 __physicalBaseScreenSize = _CoordinateSystem::GetInstance()->GetPhysicalBaseScreenSize();
91 _AppResourceBitmapUtil::~_AppResourceBitmapUtil(void)
95 _AppResourceBitmapUtil*
96 _AppResourceBitmapUtil::GetInstanceN(int type, const String& value)
98 String resourceFolder(L"");
99 Tizen::App::_AppResourceBitmapUtil::AppResourceBy appResourceType = _AppResourceBitmapUtil::APP_RESOURCE_DEFAULT;
103 case _AppResourceBitmapUtil::APP_RESOURCE_BITMAP:
104 appResourceType = _AppResourceBitmapUtil::APP_RESOURCE_BITMAP;
106 case _AppResourceBitmapUtil::APP_RESOURCE_DEFAULT:
108 case _AppResourceBitmapUtil::APP_RESOURCE_BY_LIBRARY_NAME:
111 resourceFolder = _AppInfo::GetAppRootPath();
112 resourceFolder.Append(L"res/");
113 if (!value.IsEmpty())
115 resourceFolder.Append(value);
116 resourceFolder.Append(L'/');
119 case _AppResourceBitmapUtil::APP_RESOURCE_BY_APP_ID:
120 std::unique_ptr< PackageInfo> pPkgInfo(_PackageManagerImpl::GetInstance()->GetPackageInfoN(value));
121 SysTryReturn(NID_APP, pPkgInfo != null, null, E_APP_NOT_INSTALLED, "[E_APP_NOT_INSTALLED] Failed to get the package info.");
123 _PackageInfoImpl* pPkgInfoImpl = _PackageInfoImpl::GetInstance(pPkgInfo.get());
124 SysTryReturn(NID_APP, pPkgInfoImpl != null, null, E_APP_NOT_INSTALLED, "[E_APP_NOT_INSTALLED] Failed to get the package info impl.");
126 resourceFolder = pPkgInfoImpl->GetAppRootPath();
127 resourceFolder.Append(L"/res/");
131 std::unique_ptr< _AppResourceBitmapUtil > pAppResourceBitmapUtil(new (std::nothrow) _AppResourceBitmapUtil());
132 SysTryReturn(NID_APP, pAppResourceBitmapUtil != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient." );
134 pAppResourceBitmapUtil->__resourceType = appResourceType;
136 result r = pAppResourceBitmapUtil->Construct(resourceFolder);
137 SysTryReturn(NID_APP, r == E_SUCCESS, null, r, "[%s] Failed to construct _AppResourceBitmapUtil.", GetErrorMessage(r));
139 return pAppResourceBitmapUtil.release();
143 _AppResourceBitmapUtil::Construct(const String& resourceFolder)
145 if (__resourceType == _AppResourceBitmapUtil::APP_RESOURCE_BITMAP)
147 SysLog(NID_APP, "This is a BitmapUtil for getting a non-scaling bitmap resource");
152 result r = Tizen::System::_SystemInfoImpl::GetSysInfo(L"http://tizen.org/feature/screen.dpi", deviceDPI);
153 SysTryReturnResult(NID_APP, r == E_SUCCESS, r, "[%s] Failed to get Screen DPI", GetErrorMessage(r));
155 // 1. Get directory path matched device's resolution (e.g.720x1280)
156 if (GetDirectoryPath(resourceFolder, DENSITY_NONE, __resolutionDirectories) == false)
158 __resolutionDirectories = L"";
159 SysLog(NID_APP, "Failed to get a Device Resolution Directory path");
162 // 2. Get screen density & directory path matched device's DPI (e.g.screen-density-xhigh)
163 if (deviceDPI >= DPI_FOR_XHIGH)
165 __sortedDensity[0] = DENSITY_XHIGH;
167 else if (deviceDPI >= DPI_FOR_HIGH)
169 __sortedDensity[0] = DENSITY_HIGH;
171 else if (deviceDPI >= DPI_FOR_MIDDLE)
173 __sortedDensity[0] = DENSITY_MIDDLE;
175 else if (deviceDPI < DPI_FOR_MIDDLE && deviceDPI >= DPI_FOR_LOW)
177 __sortedDensity[0] = DENSITY_LOW;
181 __sortedDensity[0] = DENSITY_XHIGH;
182 SysLog(NID_APP, "Failed to get a Device Density (DPI = %d)", deviceDPI);
185 if (GetDirectoryPath(resourceFolder, __sortedDensity[0], __sortedDensityDirectories[0]) == false)
187 __sortedDensityDirectories[0] = L"";
188 SysLog(NID_APP, "Failed to get a Device Density Directory path");
191 // 3. Get screen density & directory path with fall back system (XHIGH-HIGH-MIDDLE-LOW)
192 int densityIndex = 1;
194 for (int currentDensity = DENSITY_XHIGH; currentDensity >= DENSITY_LOW; currentDensity--)
196 SysAssert(densityIndex > DENSITY_NONE && densityIndex < DENSITY_MAX);
198 if (static_cast<int>(__sortedDensity[0]) == currentDensity)
203 __sortedDensity[densityIndex] = static_cast<_Density>(currentDensity);
205 if (GetDirectoryPath(resourceFolder, __sortedDensity[densityIndex], __sortedDensityDirectories[densityIndex]) == false)
207 __sortedDensityDirectories[densityIndex] = L"";
208 SysLog(NID_APP, "Failed to get a %dth Fall-Back Directory path", densityIndex);
217 // Get Resource DirectoryPath
219 _AppResourceBitmapUtil::GetDirectoryPath(const String& homePath, const _Density resourceDirectory, String& dirPath) const
221 switch (resourceDirectory)
224 switch (__physicalResolutionDim.width)
227 dirPath = L"720x1280";
231 dirPath = L"480x800";
235 dirPath = L"240x400";
239 dirPath = L"320x480";
248 dirPath = L"screen-density-xhigh";
252 dirPath = L"screen-density-high";
256 dirPath = L"screen-density-middle";
260 dirPath = L"screen-density-low";
268 result r = dirPath.Insert(homePath, 0);
269 SysTryReturn(NID_APP, r == E_SUCCESS, false, r, "[%s] Failed to insert string.", GetErrorMessage(r));
271 if ( File::IsFileExist(dirPath) == false )
279 // Get Resource File Path
281 _AppResourceBitmapUtil::GetFilePath(const String& directoryPath, const String& fileName, String& filePath) const
283 if (directoryPath == L"")
289 const String& normalizedPseudoPath = NormalizePath(fileName);
290 SysAssert(normalizedPseudoPath.StartsWith(L"/", 0));
292 filePath = directoryPath + normalizedPseudoPath;
298 _AppResourceBitmapUtil::NormalizePath(const String& path) const
300 String normalizedPath = path;
302 normalizedPath.Replace(L'\\', L'/');
304 if (normalizedPath.StartsWith(L"/", 0) == false)
306 result r = normalizedPath.Insert(L'/', 0);
307 SysTryLog(NID_APP, r == E_SUCCESS, "[%s] Propagating.", GetErrorMessage(r));
310 return normalizedPath;
313 // Get Matched Resource File Path
315 _AppResourceBitmapUtil::GetResourcePath(const String& fileName, String& resourcePath, _Density& resourceDensity, bool& imageScaling) const
317 result r = E_SUCCESS;
319 // 0. Try to check nine patch image
320 bool isNinePatchImage = false;
322 if (_BitmapImpl::HasNinePatchedBitmapTag(fileName))
324 isNinePatchImage = true;
325 SysLog(NID_APP, "%S is nine patch image", fileName.GetPointer());
328 // 1. Try to search resolution Folder
329 String resourcePathForResolution(L"");
331 if (__resolutionDirectories.IsEmpty() == false &&
332 GetFilePath(__resolutionDirectories, fileName, resourcePathForResolution))
334 if (File::IsFileExist(resourcePathForResolution))
336 resourcePath = resourcePathForResolution;
337 resourceDensity = DENSITY_NONE;
338 imageScaling = false;
345 // 2. Try to search resource directory matched device's DPI
346 String resourcePathForDensity(L"");
348 if (__sortedDensityDirectories[0].IsEmpty() == false &&
349 GetFilePath(__sortedDensityDirectories[0], fileName, resourcePathForDensity))
351 if (File::IsFileExist(resourcePathForDensity))
353 resourcePath = resourcePathForDensity;
354 resourceDensity = __sortedDensity[0];
355 imageScaling = isNinePatchImage ? false : _CoordinateSystem::GetInstance()->IsTransformEnabled();
362 // 3. Try to find the alternative path with fall back
363 int fallbackIndex = 1;
364 String alternativeResourcePath(L"");
366 for (int findingDensity = DENSITY_XHIGH; findingDensity > DENSITY_LOW; findingDensity--)
368 if (__sortedDensityDirectories[fallbackIndex].IsEmpty() == false &&
369 GetFilePath(__sortedDensityDirectories[fallbackIndex], fileName, alternativeResourcePath))
371 if (File::IsFileExist(alternativeResourcePath))
373 resourcePath = alternativeResourcePath;
374 resourceDensity = __sortedDensity[fallbackIndex];
375 imageScaling = !isNinePatchImage;
384 SysTryReturn(NID_APP, r == E_SUCCESS, E_FILE_NOT_FOUND, E_FILE_NOT_FOUND, "[E_FILE_NOT_FOUND] The specified file cannot be found.");
391 _AppResourceBitmapUtil::GetBitmapN(const String& resourcePath, const _Density resourceDensity,
392 BitmapPixelFormat pixelFormat, bool imageScaling, const Color* pChromaKeyColor) const
395 SysTryReturn(NID_APP, (pixelFormat > BITMAP_PIXEL_FORMAT_MIN && pixelFormat < BITMAP_PIXEL_FORMAT_MAX), null,
396 E_UNSUPPORTED_FORMAT, "[E_UNSUPPORTED_FORMAT] The image file format or specified pixel format(%d) is not supported.", pixelFormat);
398 result r = E_SUCCESS;
400 std::unique_ptr<Bitmap> pBitmap;
402 if (!pChromaKeyColor && imageScaling == false) // NonScaling
404 pBitmap.reset(new (std::nothrow) Bitmap());
405 SysTryReturn(NID_APP, pBitmap != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
407 r = _BitmapImpl::GetInstance(*pBitmap)->Construct(resourcePath, pixelFormat);
408 SysTryReturn(NID_APP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
410 return pBitmap.release();
414 MediaPixelFormat format = ConvertBitmapPixelFormatToMediaPixelFormat(pixelFormat);
418 std::unique_ptr<ByteBuffer> pBuffer(_ImageDecoder::DecodeToBufferN(resourcePath, format, imageWidth, imageHeight));
420 SysTryReturn(NID_APP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
421 SysTryReturn(NID_APP, pBuffer != null, null, E_SYSTEM, "[E_SYSTEM] A system error has occurred.");
423 pBitmap.reset(_BitmapImpl::GetNonScaledBitmapN(*pBuffer, Dimension(imageWidth, imageHeight), pixelFormat));
425 SysTryReturn(NID_APP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
426 SysTryReturn(NID_APP, pBitmap != null, null, E_SYSTEM, "[E_SYSTEM] A system error has occurred.");
428 int resourceLogicalCoordinate = __physicalResolutionDim.width;
430 switch (resourceDensity)
433 resourceLogicalCoordinate = 720;
437 resourceLogicalCoordinate = 480;
441 resourceLogicalCoordinate = 320;
445 resourceLogicalCoordinate = 240;
452 _ICoordinateSystemTransformer* pTempXformer(null);
453 r = _CreateCoordinateTransformer(pTempXformer,
454 resourceLogicalCoordinate, __physicalBaseScreenSize,
455 Dimension(_CoordinateSystem::GetInstance()->GetLogicalResolutionInt(), _CoordinateSystem::GetInstance()->GetLogicalResolutionInt()), _CoordinateSystem::GetInstance()->GetLogicalBaseScreenSize());
457 std::unique_ptr<_ICoordinateSystemTransformer> pXformer(pTempXformer);
458 SysTryReturn(NID_APP, pXformer != null, null, E_SYSTEM, "[E_SYSTEM] A system error has occurred.");
459 SysTryReturn(NID_APP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
461 FloatDimension physicalImageDim = _CoordinateSystemUtils::ConvertToFloat(Dimension(imageWidth, imageHeight));
462 FloatDimension logicalImageSize = pXformer->Transform(physicalImageDim);
464 SysTryReturn(NID_APP, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] A system error has occurred.");
466 r = pBitmap->Scale(logicalImageSize);
467 SysTryReturn(NID_APP, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] A system error has occurred.");
470 if (pChromaKeyColor != null)
472 r = pBitmap->SetMaskingColor(pChromaKeyColor);
473 SysTryReturn(NID_APP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
476 SetLastResult(E_SUCCESS);
478 return pBitmap.release();
481 Tizen::App::_AppResourceBitmapUtil::AppResourceBy
482 _AppResourceBitmapUtil::GetAppResourceType(void)
484 return __resourceType;