@nativescript/core 9.0.0-next-09-27-2025-18063560861 → 9.0.0-next-10-06-2025-18277360121

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/package.json +1 -1
  2. package/platforms/android/include.gradle +51 -0
  3. package/platforms/android/java/org/nativescript/Process.java +59 -0
  4. package/platforms/android/java/org/nativescript/widgets/AbsoluteLayout.java +88 -0
  5. package/platforms/android/java/org/nativescript/widgets/AnimatorHelper.java +61 -0
  6. package/platforms/android/java/org/nativescript/widgets/Async.java +1356 -0
  7. package/platforms/android/java/org/nativescript/widgets/BorderDrawable.java +936 -0
  8. package/platforms/android/java/org/nativescript/widgets/BottomNavigationBar.java +308 -0
  9. package/platforms/android/java/org/nativescript/widgets/BoxShadowDrawable.java +175 -0
  10. package/platforms/android/java/org/nativescript/widgets/CSSValue.java +34 -0
  11. package/platforms/android/java/org/nativescript/widgets/CommonLayoutParams.java +456 -0
  12. package/platforms/android/java/org/nativescript/widgets/ContentLayout.java +85 -0
  13. package/platforms/android/java/org/nativescript/widgets/CustomTransition.java +135 -0
  14. package/platforms/android/java/org/nativescript/widgets/CustomTypefaceSpan.java +44 -0
  15. package/platforms/android/java/org/nativescript/widgets/Dock.java +15 -0
  16. package/platforms/android/java/org/nativescript/widgets/DockLayout.java +185 -0
  17. package/platforms/android/java/org/nativescript/widgets/FileHelper.java +815 -0
  18. package/platforms/android/java/org/nativescript/widgets/FlexLine.java +177 -0
  19. package/platforms/android/java/org/nativescript/widgets/FlexboxLayout.java +2769 -0
  20. package/platforms/android/java/org/nativescript/widgets/FragmentBase.java +14 -0
  21. package/platforms/android/java/org/nativescript/widgets/GridLayout.java +1172 -0
  22. package/platforms/android/java/org/nativescript/widgets/GridUnitType.java +10 -0
  23. package/platforms/android/java/org/nativescript/widgets/HorizontalScrollView.java +256 -0
  24. package/platforms/android/java/org/nativescript/widgets/ImageView.java +423 -0
  25. package/platforms/android/java/org/nativescript/widgets/ItemSpec.java +56 -0
  26. package/platforms/android/java/org/nativescript/widgets/LayoutBase.java +98 -0
  27. package/platforms/android/java/org/nativescript/widgets/LinearGradientDefinition.java +46 -0
  28. package/platforms/android/java/org/nativescript/widgets/Orientation.java +9 -0
  29. package/platforms/android/java/org/nativescript/widgets/OriginPoint.java +74 -0
  30. package/platforms/android/java/org/nativescript/widgets/ScrollSavedState.java +63 -0
  31. package/platforms/android/java/org/nativescript/widgets/SegmentedBarColorDrawable.java +27 -0
  32. package/platforms/android/java/org/nativescript/widgets/StackLayout.java +231 -0
  33. package/platforms/android/java/org/nativescript/widgets/StyleableTextView.java +50 -0
  34. package/platforms/android/java/org/nativescript/widgets/TabIconRenderingMode.java +6 -0
  35. package/platforms/android/java/org/nativescript/widgets/TabItemSpec.java +15 -0
  36. package/platforms/android/java/org/nativescript/widgets/TabLayout.java +451 -0
  37. package/platforms/android/java/org/nativescript/widgets/TabStrip.java +294 -0
  38. package/platforms/android/java/org/nativescript/widgets/TabViewPager.java +64 -0
  39. package/platforms/android/java/org/nativescript/widgets/TabsBar.java +443 -0
  40. package/platforms/android/java/org/nativescript/widgets/Utils.java +546 -0
  41. package/platforms/android/java/org/nativescript/widgets/VerticalScrollView.java +258 -0
  42. package/platforms/android/java/org/nativescript/widgets/ViewHelper.java +564 -0
  43. package/platforms/android/java/org/nativescript/widgets/WrapLayout.java +252 -0
  44. package/platforms/android/java/org/nativescript/widgets/image/AsyncTask.java +679 -0
  45. package/platforms/android/java/org/nativescript/widgets/image/BitmapOwner.java +17 -0
  46. package/platforms/android/java/org/nativescript/widgets/image/Cache.java +471 -0
  47. package/platforms/android/java/org/nativescript/widgets/image/DiskLruCache.java +970 -0
  48. package/platforms/android/java/org/nativescript/widgets/image/Fetcher.java +747 -0
  49. package/platforms/android/java/org/nativescript/widgets/image/Utils.java +58 -0
  50. package/platforms/android/java/org/nativescript/widgets/image/Worker.java +571 -0
  51. package/platforms/ios/src/TNSWidgets/Info.plist +26 -0
  52. package/platforms/ios/src/TNSWidgets/NSData+Async.m +42 -0
  53. package/platforms/ios/src/TNSWidgets/NSFileHandle+Async.m +82 -0
  54. package/platforms/ios/src/TNSWidgets/NSObject+Swizzling.m +68 -0
  55. package/platforms/ios/src/TNSWidgets/NSString+Async.m +51 -0
  56. package/platforms/ios/src/TNSWidgets/TNSLabel.m +42 -0
  57. package/platforms/ios/src/TNSWidgets/UIImage+TNSBlocks.m +77 -0
  58. package/platforms/ios/src/TNSWidgets/UIView+PassThroughParent.m +53 -0
  59. package/platforms/ios/src/TNSWidgets/UIView+PropertyBag.m +72 -0
  60. package/platforms/ios/src/module.modulemap +5 -0
  61. package/platforms/android/widgets-release.aar +0 -0
  62. package/platforms/ios/TNSWidgets.xcframework/Info.plist +0 -102
  63. package/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/NSCCrypto.h +0 -60
  64. package/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers/TNSProcess.h +0 -29
  65. package/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Info.plist +0 -0
  66. package/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Modules/module.modulemap +0 -6
  67. package/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/TNSWidgets +0 -0
  68. package/platforms/ios/TNSWidgets.xcframework/ios-arm64/dSYMs/TNSWidgets.framework.dSYM/Contents/Info.plist +0 -20
  69. package/platforms/ios/TNSWidgets.xcframework/ios-arm64/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/DWARF/TNSWidgets +0 -0
  70. package/platforms/ios/TNSWidgets.xcframework/ios-arm64/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/Relocations/aarch64/TNSWidgets.yml +0 -82
  71. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Headers/NSCCrypto.h +0 -60
  72. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Headers/NSData+Async.h +0 -24
  73. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Headers/NSFileHandle+Async.h +0 -22
  74. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Headers/NSString+Async.h +0 -25
  75. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Headers/TNSLabel.h +0 -16
  76. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Headers/TNSProcess.h +0 -29
  77. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Headers/TNSWidgets.h +0 -25
  78. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Headers/UIImage+TNSBlocks.h +0 -26
  79. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Headers/UIView+PassThroughParent.h +0 -17
  80. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Modules/module.modulemap +0 -6
  81. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/PrivateHeaders/NSObject+Swizzling.h +0 -17
  82. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/PrivateHeaders/UIView+PropertyBag.h +0 -18
  83. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Resources/Info.plist +0 -52
  84. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Headers/NSCCrypto.h +0 -60
  85. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Headers/NSData+Async.h +0 -24
  86. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Headers/NSFileHandle+Async.h +0 -22
  87. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Headers/NSString+Async.h +0 -25
  88. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Headers/TNSLabel.h +0 -16
  89. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Headers/TNSProcess.h +0 -29
  90. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Headers/TNSWidgets.h +0 -25
  91. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Headers/UIImage+TNSBlocks.h +0 -26
  92. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Headers/UIView+PassThroughParent.h +0 -17
  93. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Modules/module.modulemap +0 -6
  94. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/PrivateHeaders/NSObject+Swizzling.h +0 -17
  95. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/PrivateHeaders/UIView+PropertyBag.h +0 -18
  96. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/Resources/Info.plist +0 -52
  97. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/A/TNSWidgets +0 -0
  98. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Headers/NSCCrypto.h +0 -60
  99. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Headers/NSData+Async.h +0 -24
  100. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Headers/NSFileHandle+Async.h +0 -22
  101. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Headers/NSString+Async.h +0 -25
  102. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Headers/TNSLabel.h +0 -16
  103. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Headers/TNSProcess.h +0 -29
  104. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Headers/TNSWidgets.h +0 -25
  105. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Headers/UIImage+TNSBlocks.h +0 -26
  106. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Headers/UIView+PassThroughParent.h +0 -17
  107. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Modules/module.modulemap +0 -6
  108. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/PrivateHeaders/NSObject+Swizzling.h +0 -17
  109. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/PrivateHeaders/UIView+PropertyBag.h +0 -18
  110. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/Resources/Info.plist +0 -52
  111. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/TNSWidgets.framework/Versions/Current/TNSWidgets +0 -0
  112. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/dSYMs/TNSWidgets.framework.dSYM/Contents/Info.plist +0 -20
  113. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/DWARF/TNSWidgets +0 -0
  114. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/Relocations/aarch64/TNSWidgets.yml +0 -82
  115. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-maccatalyst/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/Relocations/x86_64/TNSWidgets.yml +0 -82
  116. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSCCrypto.h +0 -60
  117. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSData+Async.h +0 -24
  118. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSFileHandle+Async.h +0 -22
  119. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSString+Async.h +0 -25
  120. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSLabel.h +0 -16
  121. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSProcess.h +0 -29
  122. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSWidgets.h +0 -25
  123. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/UIImage+TNSBlocks.h +0 -26
  124. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Headers/UIView+PassThroughParent.h +0 -17
  125. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Info.plist +0 -0
  126. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/Modules/module.modulemap +0 -6
  127. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/PrivateHeaders/NSObject+Swizzling.h +0 -17
  128. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/PrivateHeaders/UIView+PropertyBag.h +0 -18
  129. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/TNSWidgets +0 -0
  130. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/TNSWidgets.framework/_CodeSignature/CodeResources +0 -223
  131. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Info.plist +0 -20
  132. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/DWARF/TNSWidgets +0 -0
  133. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/Relocations/aarch64/TNSWidgets.yml +0 -82
  134. package/platforms/ios/TNSWidgets.xcframework/ios-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/Relocations/x86_64/TNSWidgets.yml +0 -82
  135. package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Headers/NSCCrypto.h +0 -60
  136. package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Headers/NSData+Async.h +0 -24
  137. package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Headers/NSFileHandle+Async.h +0 -22
  138. package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Headers/NSString+Async.h +0 -25
  139. package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Headers/TNSLabel.h +0 -16
  140. package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Headers/TNSProcess.h +0 -29
  141. package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Headers/TNSWidgets.h +0 -25
  142. package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Headers/UIImage+TNSBlocks.h +0 -26
  143. package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Headers/UIView+PassThroughParent.h +0 -17
  144. package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Info.plist +0 -0
  145. package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/Modules/module.modulemap +0 -6
  146. package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/PrivateHeaders/NSObject+Swizzling.h +0 -17
  147. package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/PrivateHeaders/UIView+PropertyBag.h +0 -18
  148. package/platforms/ios/TNSWidgets.xcframework/xros-arm64/TNSWidgets.framework/TNSWidgets +0 -0
  149. package/platforms/ios/TNSWidgets.xcframework/xros-arm64/dSYMs/TNSWidgets.framework.dSYM/Contents/Info.plist +0 -20
  150. package/platforms/ios/TNSWidgets.xcframework/xros-arm64/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/DWARF/TNSWidgets +0 -0
  151. package/platforms/ios/TNSWidgets.xcframework/xros-arm64/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/Relocations/aarch64/TNSWidgets.yml +0 -82
  152. package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSCCrypto.h +0 -60
  153. package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSData+Async.h +0 -24
  154. package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSFileHandle+Async.h +0 -22
  155. package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Headers/NSString+Async.h +0 -25
  156. package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSLabel.h +0 -16
  157. package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSProcess.h +0 -29
  158. package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Headers/TNSWidgets.h +0 -25
  159. package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Headers/UIImage+TNSBlocks.h +0 -26
  160. package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Headers/UIView+PassThroughParent.h +0 -17
  161. package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Info.plist +0 -0
  162. package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/Modules/module.modulemap +0 -6
  163. package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/PrivateHeaders/NSObject+Swizzling.h +0 -17
  164. package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/PrivateHeaders/UIView+PropertyBag.h +0 -18
  165. package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/TNSWidgets +0 -0
  166. package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/TNSWidgets.framework/_CodeSignature/CodeResources +0 -223
  167. package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Info.plist +0 -20
  168. package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/DWARF/TNSWidgets +0 -0
  169. package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/Relocations/aarch64/TNSWidgets.yml +0 -82
  170. package/platforms/ios/TNSWidgets.xcframework/xros-arm64_x86_64-simulator/dSYMs/TNSWidgets.framework.dSYM/Contents/Resources/Relocations/x86_64/TNSWidgets.yml +0 -82
  171. /package/platforms/ios/{TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers → src/TNSWidgets}/NSData+Async.h +0 -0
  172. /package/platforms/ios/{TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers → src/TNSWidgets}/NSFileHandle+Async.h +0 -0
  173. /package/platforms/ios/{TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/PrivateHeaders → src/TNSWidgets}/NSObject+Swizzling.h +0 -0
  174. /package/platforms/ios/{TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers → src/TNSWidgets}/NSString+Async.h +0 -0
  175. /package/platforms/ios/{TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers → src/TNSWidgets}/TNSLabel.h +0 -0
  176. /package/platforms/ios/{TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers → src/TNSWidgets}/TNSWidgets.h +0 -0
  177. /package/platforms/ios/{TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers → src/TNSWidgets}/UIImage+TNSBlocks.h +0 -0
  178. /package/platforms/ios/{TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/Headers → src/TNSWidgets}/UIView+PassThroughParent.h +0 -0
  179. /package/platforms/ios/{TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework/PrivateHeaders → src/TNSWidgets}/UIView+PropertyBag.h +0 -0
@@ -0,0 +1,747 @@
1
+ /*
2
+ * Copyright (C) 2012 The Android Open Source Project
3
+ *
4
+ * Licensed under the Apache License, Version 2.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
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
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.
15
+ */
16
+
17
+ package org.nativescript.widgets.image;
18
+
19
+ import android.annotation.TargetApi;
20
+ import android.content.ContentResolver;
21
+ import android.content.Context;
22
+ import android.content.res.Resources;
23
+ import android.graphics.Bitmap;
24
+ import android.graphics.BitmapFactory;
25
+ import android.graphics.Matrix;
26
+ import android.net.Uri;
27
+ import android.os.Build;
28
+ import android.os.ParcelFileDescriptor;
29
+ import android.util.Log;
30
+ import android.util.TypedValue;
31
+
32
+ import androidx.exifinterface.media.ExifInterface;
33
+
34
+ import java.io.BufferedInputStream;
35
+ import java.io.BufferedOutputStream;
36
+ import java.io.ByteArrayInputStream;
37
+ import java.io.ByteArrayOutputStream;
38
+ import java.io.File;
39
+ import java.io.FileDescriptor;
40
+ import java.io.FileInputStream;
41
+ import java.io.FileNotFoundException;
42
+ import java.io.IOException;
43
+ import java.io.InputStream;
44
+ import java.io.OutputStream;
45
+ import java.net.HttpURLConnection;
46
+ import java.net.URL;
47
+
48
+ /**
49
+ * A simple subclass of {@link Worker} that fetch and resize images from a file, resource or URL.
50
+ */
51
+ public class Fetcher extends Worker {
52
+ private static final int HTTP_CACHE_SIZE = 10 * 1024 * 1024; // 10MB
53
+ private static final String HTTP_CACHE_DIR = "http";
54
+ private static final int IO_BUFFER_SIZE = 8 * 1024;
55
+
56
+ private static int mDeviceWidthPixels;
57
+ private static int mDeviceHeightPixels;
58
+
59
+ private final File mHttpCacheDir;
60
+ private DiskLruCache mHttpDiskCache;
61
+ private boolean mHttpDiskCacheStarting = true;
62
+ private final Object mHttpDiskCacheLock = new Object();
63
+ private static final int DISK_CACHE_INDEX = 0;
64
+
65
+ private final String mPackageName;
66
+ private static Fetcher instance;
67
+
68
+ public static Fetcher getInstance(Context context) {
69
+ if (instance == null) {
70
+ instance = new Fetcher(context);
71
+ }
72
+
73
+ return instance;
74
+ }
75
+
76
+ /**
77
+ * Initialize providing a target image width and height for the processing images.
78
+ *
79
+ * @param context
80
+ */
81
+ private Fetcher(Context context) {
82
+ super(context);
83
+ mHttpCacheDir = Cache.getDiskCacheDir(context, HTTP_CACHE_DIR);
84
+ mPackageName = context.getPackageName();
85
+ mDeviceWidthPixels = context.getResources().getDisplayMetrics().widthPixels;
86
+ mDeviceHeightPixels = context.getResources().getDisplayMetrics().heightPixels;
87
+ }
88
+
89
+ @Override
90
+ protected void initDiskCacheInternal() {
91
+ if (!mHttpCacheDir.exists()) {
92
+ mHttpCacheDir.mkdirs();
93
+ }
94
+ synchronized (mHttpDiskCacheLock) {
95
+ if (Cache.getUsableSpace(mHttpCacheDir) > HTTP_CACHE_SIZE) {
96
+ try {
97
+ mHttpDiskCache = DiskLruCache.open(mHttpCacheDir, 1, 1, HTTP_CACHE_SIZE);
98
+ if (debuggable > 0) {
99
+ Log.v(TAG, "HTTP cache initialized");
100
+ }
101
+ } catch (IOException e) {
102
+ mHttpDiskCache = null;
103
+ }
104
+ }
105
+ mHttpDiskCacheStarting = false;
106
+ mHttpDiskCacheLock.notifyAll();
107
+ }
108
+ }
109
+
110
+ @Override
111
+ protected void clearCacheInternal() {
112
+ super.clearCacheInternal();
113
+ synchronized (mHttpDiskCacheLock) {
114
+ if (mHttpDiskCache != null && !mHttpDiskCache.isClosed()) {
115
+ try {
116
+ mHttpDiskCache.delete();
117
+ if (debuggable > 0) {
118
+ Log.v(TAG, "HTTP cache cleared");
119
+ }
120
+ } catch (IOException e) {
121
+ Log.e(TAG, "clearCacheInternal - " + e);
122
+ }
123
+ mHttpDiskCache = null;
124
+ mHttpDiskCacheStarting = true;
125
+ }
126
+ }
127
+ }
128
+
129
+ @Override
130
+ protected void flushCacheInternal() {
131
+ synchronized (mHttpDiskCacheLock) {
132
+ if (mHttpDiskCache != null) {
133
+ try {
134
+ mHttpDiskCache.flush();
135
+ if (debuggable > 0) {
136
+ Log.v(TAG, "HTTP cache flushed");
137
+ }
138
+ } catch (IOException e) {
139
+ Log.e(TAG, "flush - " + e);
140
+ }
141
+ }
142
+ }
143
+ }
144
+
145
+ @Override
146
+ protected void closeCacheInternal() {
147
+ synchronized (mHttpDiskCacheLock) {
148
+ if (mHttpDiskCache != null) {
149
+ try {
150
+ if (!mHttpDiskCache.isClosed()) {
151
+ mHttpDiskCache.close();
152
+ mHttpDiskCache = null;
153
+ if (debuggable > 0) {
154
+ Log.v(TAG, "HTTP cache closed");
155
+ }
156
+ }
157
+ } catch (IOException e) {
158
+ Log.e(TAG, "closeCacheInternal - " + e);
159
+ }
160
+ }
161
+ }
162
+ }
163
+
164
+ /**
165
+ * The main process method, which will be called by the Worker in the AsyncTask background
166
+ * thread.
167
+ *
168
+ * @param data The data to load the bitmap, in this case, a regular http URL
169
+ * @return The downloaded and resized bitmap
170
+ */
171
+ private Bitmap processHttp(String data, int decodeWidth, int decodeHeight, boolean keepAspectRatio) {
172
+ final String key = Cache.hashKeyForDisk(data);
173
+ FileDescriptor fileDescriptor = null;
174
+ FileInputStream fileInputStream = null;
175
+ DiskLruCache.Snapshot snapshot;
176
+ synchronized (mHttpDiskCacheLock) {
177
+ // Wait for disk cache to initialize
178
+ while (mHttpDiskCacheStarting) {
179
+ try {
180
+ mHttpDiskCacheLock.wait();
181
+ } catch (InterruptedException e) {
182
+ }
183
+ }
184
+
185
+ if (mHttpDiskCache != null) {
186
+ try {
187
+ snapshot = mHttpDiskCache.get(key);
188
+ if (snapshot == null) {
189
+ if (debuggable > 0) {
190
+ Log.v(TAG, "processBitmap, not found in http cache, downloading...");
191
+ }
192
+ DiskLruCache.Editor editor = mHttpDiskCache.edit(key);
193
+ if (editor != null) {
194
+ if (downloadUrlToStream(data, editor.newOutputStream(DISK_CACHE_INDEX))) {
195
+ editor.commit();
196
+ } else {
197
+ editor.abort();
198
+ }
199
+ }
200
+ snapshot = mHttpDiskCache.get(key);
201
+ }
202
+ if (snapshot != null) {
203
+ fileInputStream = (FileInputStream) snapshot.getInputStream(DISK_CACHE_INDEX);
204
+ fileDescriptor = fileInputStream.getFD();
205
+ }
206
+ } catch (IOException e) {
207
+ Log.e(TAG, "processHttp - " + e);
208
+ } catch (IllegalStateException e) {
209
+ Log.e(TAG, "processHttp - " + e);
210
+ } finally {
211
+ if (fileDescriptor == null && fileInputStream != null) {
212
+ try {
213
+ fileInputStream.close();
214
+ } catch (IOException e) {
215
+ }
216
+ }
217
+ }
218
+ }
219
+ }
220
+
221
+ Bitmap bitmap = null;
222
+ if (fileDescriptor != null) {
223
+ bitmap = decodeSampledBitmapFromDescriptor(fileDescriptor, decodeWidth, decodeHeight, keepAspectRatio,
224
+ getCache());
225
+ }
226
+ if (fileInputStream != null) {
227
+ try {
228
+ fileInputStream.close();
229
+ } catch (IOException e) {
230
+ }
231
+ }
232
+ return bitmap;
233
+ }
234
+
235
+ private Bitmap processHttpNoCache(String data, int decodeWidth, int decodeHeight, boolean keepAspectRatio) {
236
+ ByteArrayOutputStreamInternal outputStream = null;
237
+ Bitmap bitmap = null;
238
+
239
+ try {
240
+ outputStream = new ByteArrayOutputStreamInternal();
241
+ if (downloadUrlToStream(data, outputStream)) {
242
+ bitmap = decodeSampledBitmapFromByteArray(outputStream.getBuffer(), decodeWidth, decodeHeight,
243
+ keepAspectRatio, getCache());
244
+ }
245
+ } catch (IllegalStateException e) {
246
+ Log.e(TAG, "processHttpNoCache - " + e);
247
+ } finally {
248
+ if (outputStream != null) {
249
+ try {
250
+ outputStream.close();
251
+ } catch (IOException e) {
252
+ }
253
+ }
254
+ }
255
+
256
+ return bitmap;
257
+ }
258
+
259
+ @Override
260
+ protected Bitmap processBitmap(String uri, int decodeWidth, int decodeHeight, boolean keepAspectRatio,
261
+ boolean useCache) {
262
+ if (debuggable > 0) {
263
+ Log.v(TAG, "process: " + uri);
264
+ }
265
+ if (uri.startsWith(CONTENT_PREFIX)) {
266
+ return decodeSampledBitmapFromContent(uri, mResolver, decodeWidth, decodeHeight, keepAspectRatio, getCache());
267
+ } else if (uri.startsWith(FILE_PREFIX)) {
268
+ String filename = uri.substring(FILE_PREFIX.length());
269
+ return decodeSampledBitmapFromFile(filename, decodeWidth, decodeHeight, keepAspectRatio, getCache());
270
+ } else if (uri.startsWith(RESOURCE_PREFIX)) {
271
+ String resPath = uri.substring(RESOURCE_PREFIX.length());
272
+ int resId = mResources.getIdentifier(resPath, "drawable", mPackageName);
273
+ if (resId > 0) {
274
+ return decodeSampledBitmapFromResource(mResources, resId, decodeWidth, decodeHeight, keepAspectRatio,
275
+ getCache());
276
+ } else {
277
+ Log.v(TAG, "Missing Image with resourceID: " + uri);
278
+ return null;
279
+ }
280
+ } else {
281
+ if (useCache && mHttpDiskCache != null) {
282
+ return processHttp(uri, decodeWidth, decodeHeight, keepAspectRatio);
283
+ } else {
284
+ return processHttpNoCache(uri, decodeWidth, decodeHeight, keepAspectRatio);
285
+ }
286
+ }
287
+ }
288
+
289
+ /**
290
+ * Download a bitmap from a URL and write the content to an output stream.
291
+ *
292
+ * @param urlString The URL to fetch
293
+ * @return true if successful, false otherwise
294
+ */
295
+ public boolean downloadUrlToStream(String urlString, OutputStream outputStream) {
296
+ disableConnectionReuseIfNecessary();
297
+ HttpURLConnection urlConnection = null;
298
+ BufferedOutputStream out = null;
299
+ BufferedInputStream in = null;
300
+
301
+ try {
302
+ final URL url = new URL(urlString);
303
+ urlConnection = (HttpURLConnection) url.openConnection();
304
+ in = new BufferedInputStream(urlConnection.getInputStream(), IO_BUFFER_SIZE);
305
+ out = new BufferedOutputStream(outputStream, IO_BUFFER_SIZE);
306
+
307
+ int b;
308
+ while ((b = in.read()) != -1) {
309
+ out.write(b);
310
+ }
311
+ return true;
312
+ } catch (final IOException e) {
313
+ Log.e(TAG, "Error in downloadBitmap - " + e);
314
+ } finally {
315
+ if (urlConnection != null) {
316
+ urlConnection.disconnect();
317
+ }
318
+ try {
319
+ if (out != null) {
320
+ out.close();
321
+ }
322
+ if (in != null) {
323
+ in.close();
324
+ }
325
+ } catch (final IOException e) {
326
+ }
327
+ }
328
+ return false;
329
+ }
330
+
331
+ /**
332
+ * Workaround for bug pre-Froyo, see here for more info:
333
+ * http://android-developers.blogspot.com/2011/09/androids-http-clients.html
334
+ */
335
+ public static void disableConnectionReuseIfNecessary() {
336
+ // HTTP connection reuse which was buggy pre-froyo
337
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) {
338
+ System.setProperty("http.keepAlive", "false");
339
+ }
340
+ }
341
+
342
+ private static class ByteArrayOutputStreamInternal extends ByteArrayOutputStream {
343
+ public byte[] getBuffer() {
344
+ return buf;
345
+ }
346
+ }
347
+
348
+ /**
349
+ * Decode and sample down a bitmap from resources to the requested width and height.
350
+ *
351
+ * @param res The resources object containing the image data
352
+ * @param resId The resource id of the image data
353
+ * @param reqWidth The requested width of the resulting bitmap
354
+ * @param reqHeight The requested height of the resulting bitmap
355
+ * @param cache The Cache used to find candidate bitmaps for use with inBitmap
356
+ * @return A bitmap sampled down from the original with the same aspect ratio and dimensions
357
+ * that are equal to or greater than the requested width and height
358
+ */
359
+ public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight,
360
+ boolean keepAspectRatio, Cache cache) {
361
+
362
+ // BEGIN_INCLUDE (read_bitmap_dimensions)
363
+ // First decode with inJustDecodeBounds=true to check dimensions
364
+ final BitmapFactory.Options options = new BitmapFactory.Options();
365
+ options.inJustDecodeBounds = true;
366
+ BitmapFactory.decodeResource(res, resId, options);
367
+
368
+ options.inSampleSize = calculateInSampleSize(options.outWidth, options.outHeight, reqWidth, reqHeight);
369
+
370
+ // END_INCLUDE (read_bitmap_dimensions)
371
+
372
+ // If we're running on Honeycomb or newer, try to use inBitmap
373
+ if (Utils.hasHoneycomb()) {
374
+ addInBitmapOptions(options, cache);
375
+ }
376
+
377
+ // Decode bitmap with inSampleSize set
378
+ options.inJustDecodeBounds = false;
379
+ Bitmap bitmap = null;
380
+ InputStream is = null;
381
+
382
+ try {
383
+ final TypedValue value = new TypedValue();
384
+ is = res.openRawResource(resId, value);
385
+ bitmap = BitmapFactory.decodeResourceStream(res, value, is, null, options);
386
+ } catch (Exception e) {
387
+ /* do nothing.
388
+ If the exception happened on open, bm will be null.
389
+ If it happened on close, bm is still valid.
390
+ */
391
+ }
392
+
393
+
394
+ if (bitmap == null) {
395
+ // throw new IllegalArgumentException("Problem decoding into existing bitmap");
396
+ return null;
397
+ }
398
+
399
+ ExifInterface ei = getExifInterface(is);
400
+
401
+ return scaleAndRotateBitmap(bitmap, ei, reqWidth, reqHeight, keepAspectRatio);
402
+ }
403
+
404
+ @TargetApi(Build.VERSION_CODES.N)
405
+ private static ExifInterface getExifInterface(InputStream is) {
406
+ ExifInterface ei = null;
407
+ try {
408
+ if (Utils.hasN()) {
409
+ ei = new ExifInterface(is);
410
+ }
411
+ } catch (final Exception e) {
412
+ Log.e(TAG, "Error in reading bitmap - " + e);
413
+ } finally {
414
+ if (is != null) {
415
+ try {
416
+ is.close();
417
+ } catch (IOException e) {
418
+ }
419
+ }
420
+ }
421
+
422
+ return ei;
423
+ }
424
+
425
+ @TargetApi(Build.VERSION_CODES.N)
426
+ private static ExifInterface getExifInterface(FileDescriptor fd) {
427
+ ExifInterface ei = null;
428
+ try {
429
+ if (Utils.hasN()) {
430
+ ei = new ExifInterface(fd);
431
+ }
432
+ } catch (final Exception e) {
433
+ Log.e(TAG, "Error in reading bitmap - " + e);
434
+ }
435
+
436
+ return ei;
437
+ }
438
+
439
+ private static ExifInterface getExifInterface(String fileName) {
440
+ ExifInterface ei = null;
441
+ try {
442
+ ei = new ExifInterface(fileName);
443
+ } catch (final Exception e) {
444
+ Log.e(TAG, "Error in reading bitmap - " + e);
445
+ }
446
+
447
+ return ei;
448
+ }
449
+
450
+ /**
451
+ * Decode and sample down a bitmap from a file to the requested width and height.
452
+ *
453
+ * @param fileName The full path of the file to decode
454
+ * @param reqWidth The requested width of the resulting bitmap
455
+ * @param reqHeight The requested height of the resulting bitmap
456
+ * @param cache The Cache used to find candidate bitmaps for use with inBitmap
457
+ * @return A bitmap sampled down from the original with the same aspect ratio and dimensions
458
+ * that are equal to or greater than the requested width and height
459
+ */
460
+ public static Bitmap decodeSampledBitmapFromFile(String fileName, int reqWidth, int reqHeight,
461
+ boolean keepAspectRatio, Cache cache) {
462
+
463
+ // First decode with inJustDecodeBounds=true to check dimensions
464
+ final BitmapFactory.Options options = new BitmapFactory.Options();
465
+ options.inJustDecodeBounds = true;
466
+ BitmapFactory.decodeFile(fileName, options);
467
+
468
+ options.inSampleSize = calculateInSampleSize(options.outWidth, options.outHeight, reqWidth, reqHeight);
469
+
470
+ // If we're running on Honeycomb or newer, try to use inBitmap
471
+ if (Utils.hasHoneycomb()) {
472
+ addInBitmapOptions(options, cache);
473
+ }
474
+
475
+ // Decode bitmap with inSampleSize set
476
+ options.inJustDecodeBounds = false;
477
+
478
+ final Bitmap bitmap = BitmapFactory.decodeFile(fileName, options);
479
+ ExifInterface ei = getExifInterface(fileName);
480
+
481
+ return scaleAndRotateBitmap(bitmap, ei, reqWidth, reqHeight, keepAspectRatio);
482
+ }
483
+
484
+ private static void closePfd(ParcelFileDescriptor pfd) {
485
+ if (pfd != null) {
486
+ try {
487
+ pfd.close();
488
+ } catch (IOException ignored) {
489
+ }
490
+ }
491
+ }
492
+
493
+ /**
494
+ * Decode and sample down a bitmap from a file to the requested width and height.
495
+ *
496
+ * @param content The content uri of the file to decode
497
+ * @param reqWidth The requested width of the resulting bitmap
498
+ * @param reqHeight The requested height of the resulting bitmap
499
+ * @param cache The Cache used to find candidate bitmaps for use with inBitmap
500
+ * @return A bitmap sampled down from the original with the same aspect ratio and dimensions
501
+ * that are equal to or greater than the requested width and height
502
+ */
503
+ public static Bitmap decodeSampledBitmapFromContent(String content, ContentResolver resolver, int reqWidth, int reqHeight,
504
+ boolean keepAspectRatio, Cache cache) {
505
+
506
+ // First decode with inJustDecodeBounds=true to check dimensions
507
+ final BitmapFactory.Options options = new BitmapFactory.Options();
508
+ options.inJustDecodeBounds = true;
509
+
510
+
511
+ Uri uri = android.net.Uri.parse(content);
512
+ ParcelFileDescriptor pfd = null;
513
+ try {
514
+ pfd = resolver.openFileDescriptor(uri, "r");
515
+ BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor(), null, options);
516
+ } catch (FileNotFoundException e) {
517
+ Log.v(TAG, "File not found " + content);
518
+ closePfd(pfd);
519
+ return null;
520
+ }
521
+
522
+
523
+ options.inSampleSize = calculateInSampleSize(options.outWidth, options.outHeight, reqWidth, reqHeight);
524
+
525
+ // If we're running on Honeycomb or newer, try to use inBitmap
526
+ if (Utils.hasHoneycomb()) {
527
+ addInBitmapOptions(options, cache);
528
+ }
529
+
530
+ // Decode bitmap with inSampleSize set
531
+ options.inJustDecodeBounds = false;
532
+
533
+ final Bitmap bitmap = BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor(), null, options);
534
+
535
+ ExifInterface ei = getExifInterface(pfd.getFileDescriptor());
536
+ closePfd(pfd);
537
+
538
+ return scaleAndRotateBitmap(bitmap, ei, reqWidth, reqHeight, keepAspectRatio);
539
+ }
540
+
541
+ private static Bitmap scaleAndRotateBitmap(Bitmap bitmap, ExifInterface ei, int reqWidth, int reqHeight,
542
+ boolean keepAspectRatio) {
543
+ if (bitmap == null) {
544
+ return null;
545
+ }
546
+
547
+ int sourceWidth = bitmap.getWidth();
548
+ int sourceHeight = bitmap.getHeight();
549
+
550
+ reqWidth = reqWidth > 0 ? reqWidth : Math.min(sourceWidth, mDeviceWidthPixels);
551
+ reqHeight = reqHeight > 0 ? reqHeight : Math.min(sourceHeight, mDeviceHeightPixels);
552
+
553
+ // scale
554
+ if (reqWidth != sourceWidth || reqHeight != sourceHeight) {
555
+ boolean needsResize;
556
+
557
+ if (keepAspectRatio) {
558
+ double widthCoef = (double) sourceWidth / (double) reqWidth;
559
+ double heightCoef = (double) sourceHeight / (double) reqHeight;
560
+ double aspectCoef = Math.min(widthCoef, heightCoef);
561
+
562
+ reqWidth = (int) Math.floor(sourceWidth / aspectCoef);
563
+ reqHeight = (int) Math.floor(sourceHeight / aspectCoef);
564
+
565
+ // Update resize flag as values might revert back to original
566
+ needsResize = reqWidth != sourceWidth || reqHeight != sourceHeight;
567
+ } else {
568
+ needsResize = true;
569
+ }
570
+
571
+ // After preserving aspect ratio, check if bitmap still needs scaling
572
+ if (needsResize) {
573
+ bitmap = Bitmap.createScaledBitmap(bitmap, reqWidth, reqHeight, true);
574
+ }
575
+ }
576
+
577
+ // rotate
578
+ if (ei != null) {
579
+ final Matrix matrix = new Matrix();
580
+ final int rotationAngle = calculateRotationAngle(ei);
581
+ if (rotationAngle != 0) {
582
+ matrix.postRotate(rotationAngle);
583
+ bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
584
+ }
585
+ }
586
+
587
+ return bitmap;
588
+ }
589
+
590
+ private static int calculateRotationAngle(ExifInterface ei) {
591
+ int rotationAngle = 0;
592
+ final int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
593
+
594
+ switch (orientation) {
595
+ case ExifInterface.ORIENTATION_ROTATE_90:
596
+ rotationAngle = 90;
597
+ break;
598
+ case ExifInterface.ORIENTATION_ROTATE_180:
599
+ rotationAngle = 180;
600
+ break;
601
+ case ExifInterface.ORIENTATION_ROTATE_270:
602
+ rotationAngle = 270;
603
+ break;
604
+ }
605
+
606
+ return rotationAngle;
607
+ }
608
+
609
+ /**
610
+ * Decode and sample down a bitmap from a file input stream to the requested width and height.
611
+ *
612
+ * @param fileDescriptor The file descriptor to read from
613
+ * @param reqWidth The requested width of the resulting bitmap
614
+ * @param reqHeight The requested height of the resulting bitmap
615
+ * @param cache The Cache used to find candidate bitmaps for use with inBitmap
616
+ * @return A bitmap sampled down from the original with the same aspect ratio and dimensions
617
+ * that are equal to or greater than the requested width and height
618
+ */
619
+ public static Bitmap decodeSampledBitmapFromDescriptor(FileDescriptor fileDescriptor, int reqWidth, int reqHeight,
620
+ boolean keepAspectRatio, Cache cache) {
621
+
622
+ // First decode with inJustDecodeBounds=true to check dimensions
623
+ final BitmapFactory.Options options = new BitmapFactory.Options();
624
+ options.inJustDecodeBounds = true;
625
+ BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
626
+
627
+ options.inSampleSize = calculateInSampleSize(options.outWidth, options.outHeight, reqWidth, reqHeight);
628
+
629
+ // Decode bitmap with inSampleSize set
630
+ options.inJustDecodeBounds = false;
631
+
632
+ // If we're running on Honeycomb or newer, try to use inBitmap
633
+ if (Utils.hasHoneycomb()) {
634
+ addInBitmapOptions(options, cache);
635
+ }
636
+
637
+ Bitmap results = null;
638
+ try {
639
+ // This can throw an error on a corrupted image when using an inBitmap
640
+ results = BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
641
+ } catch (Exception e) {
642
+ // clear the inBitmap and try again
643
+ options.inBitmap = null;
644
+ results = BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
645
+ // If image is broken, rather than an issue with the inBitmap, we will get a NULL out in this case...
646
+ }
647
+
648
+ ExifInterface ei = getExifInterface(fileDescriptor);
649
+
650
+ return scaleAndRotateBitmap(results, ei, reqWidth, reqHeight, keepAspectRatio);
651
+ }
652
+
653
+ public static Bitmap decodeSampledBitmapFromByteArray(byte[] buffer, int reqWidth, int reqHeight,
654
+ boolean keepAspectRatio, Cache cache) {
655
+
656
+ // First decode with inJustDecodeBounds=true to check dimensions
657
+ final BitmapFactory.Options options = new BitmapFactory.Options();
658
+ options.inJustDecodeBounds = true;
659
+ BitmapFactory.decodeByteArray(buffer, 0, buffer.length, options);
660
+
661
+ options.inSampleSize = calculateInSampleSize(options.outWidth, options.outHeight, reqWidth, reqHeight);
662
+
663
+ // Decode bitmap with inSampleSize set
664
+ options.inJustDecodeBounds = false;
665
+
666
+ // If we're running on Honeycomb or newer, try to use inBitmap
667
+ if (Utils.hasHoneycomb()) {
668
+ addInBitmapOptions(options, cache);
669
+ }
670
+
671
+ final Bitmap bitmap = BitmapFactory.decodeByteArray(buffer, 0, buffer.length, options);
672
+
673
+ InputStream is = new ByteArrayInputStream(buffer);
674
+ ExifInterface ei = getExifInterface(is);
675
+
676
+ return scaleAndRotateBitmap(bitmap, ei, reqWidth, reqHeight, keepAspectRatio);
677
+ }
678
+
679
+ /**
680
+ * Calculate an inSampleSize for use in a {@link BitmapFactory.Options} object when decoding
681
+ * bitmaps using the decode* methods from {@link BitmapFactory}. This implementation calculates
682
+ * the closest inSampleSize that is a power of 2 and will result in the final decoded bitmap
683
+ * having a width and height equal to or larger than the requested width and height.
684
+ *
685
+ * @param imageWidth The original width of the resulting bitmap
686
+ * @param imageHeight The original height of the resulting bitmap
687
+ * @param reqWidth The requested width of the resulting bitmap
688
+ * @param reqHeight The requested height of the resulting bitmap
689
+ * @return The value to be used for inSampleSize
690
+ */
691
+ public static int calculateInSampleSize(int imageWidth, int imageHeight, int reqWidth, int reqHeight) {
692
+ // BEGIN_INCLUDE (calculate_sample_size)
693
+ // Raw height and width of image
694
+ final int height = imageHeight;
695
+ final int width = imageWidth;
696
+ reqWidth = reqWidth > 0 ? reqWidth : width;
697
+ reqHeight = reqHeight > 0 ? reqHeight : height;
698
+ int inSampleSize = 1;
699
+ if (height > reqHeight || width > reqWidth) {
700
+
701
+ final int halfHeight = height / 2;
702
+ final int halfWidth = width / 2;
703
+
704
+ // Calculate the largest inSampleSize value that is a power of 2 and keeps both
705
+ // height and width larger than the requested height and width.
706
+ while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
707
+ inSampleSize *= 2;
708
+ }
709
+
710
+ // This offers some additional logic in case the image has a strange
711
+ // aspect ratio. For example, a panorama may have a much larger
712
+ // width than height. In these cases the total pixels might still
713
+ // end up being too large to fit comfortably in memory, so we should
714
+ // be more aggressive with sample down the image (=larger inSampleSize).
715
+
716
+ long totalPixels = (width / inSampleSize) * (height / inSampleSize);
717
+
718
+ // Anything more than 2x the requested pixels we'll sample down further
719
+ final long totalReqPixelsCap = reqWidth * reqHeight * 2;
720
+
721
+ while (totalPixels > totalReqPixelsCap) {
722
+ inSampleSize *= 2;
723
+ totalPixels = (width / inSampleSize) * (height / inSampleSize);
724
+ }
725
+ }
726
+ return inSampleSize;
727
+ // END_INCLUDE (calculate_sample_size)
728
+ }
729
+
730
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
731
+ private static void addInBitmapOptions(BitmapFactory.Options options, Cache cache) {
732
+ //BEGIN_INCLUDE(add_bitmap_options)
733
+ // inBitmap only works with mutable bitmaps so force the decoder to
734
+ // return mutable bitmaps.
735
+ options.inMutable = true;
736
+
737
+ if (cache != null) {
738
+ // Try and find a bitmap to use for inBitmap
739
+ Bitmap inBitmap = cache.getBitmapFromReusableSet(options);
740
+
741
+ if (inBitmap != null) {
742
+ options.inBitmap = inBitmap;
743
+ }
744
+ }
745
+ //END_INCLUDE(add_bitmap_options)
746
+ }
747
+ }