diff options
-rw-r--r-- | BUILD.gn | 40 | ||||
-rw-r--r-- | gn/checkdir.py | 15 | ||||
-rw-r--r-- | site/user/sample/viewer.md | 2 | ||||
-rw-r--r-- | src/ports/SkOSFile_ios.h | 41 | ||||
-rw-r--r-- | src/ports/SkOSFile_posix.cpp | 21 | ||||
-rw-r--r-- | src/ports/SkOSFile_stdio.cpp | 56 |
6 files changed, 136 insertions, 39 deletions
@@ -983,6 +983,37 @@ if (skia_enable_tools) { ] } + bundle_ios_data = + defined(invoker.bundle_ios_data) && invoker.bundle_ios_data + + if (bundle_ios_data) { + has_skps = + "True" == exec_script("//gn/checkdir.py", + [ rebase_path("skps", root_build_dir) ], + "trim string") + bundle_data("${app_name}_bundle_resources") { + sources = [ + "resources", + ] + outputs = [ + # iOS reserves the folders 'Resources' and 'resources' so store one level deeper + "{{bundle_resources_dir}}/data/resources", + ] + } + + if (has_skps) { + bundle_data("${app_name}_bundle_skps") { + sources = [ + "skps", + ] + outputs = [ + # Store in same folder as resources + "{{bundle_resources_dir}}/data/skps", + ] + } + } + } + executable("${app_name}_generate_executable") { forward_variables_from(invoker, "*", @@ -1022,6 +1053,12 @@ if (skia_enable_tools) { ":${app_name}_bundle_executable", ":${app_name}_bundle_info_plist", ] + if (bundle_ios_data) { + deps += [ ":${app_name}_bundle_resources" ] + if (has_skps) { + deps += [ ":${app_name}_bundle_skps" ] + } + } # should only code sign when running on a device, not the simulator if (target_cpu != "x64") { @@ -1747,6 +1784,9 @@ if (skia_enable_tools) { if (skia_enable_gpu) { test_app("viewer") { is_shared_library = is_android + if (is_ios) { + bundle_ios_data = true + } sources = [ "tools/viewer/GMSlide.cpp", "tools/viewer/ImageSlide.cpp", diff --git a/gn/checkdir.py b/gn/checkdir.py new file mode 100644 index 0000000000..4de7e80203 --- /dev/null +++ b/gn/checkdir.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python +# +# Copyright 2017 Google Inc. +# +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import os +import sys + +dirpath, = sys.argv[1:] + +print os.path.isdir(dirpath) + + diff --git a/site/user/sample/viewer.md b/site/user/sample/viewer.md index 340c3e1896..f30888dd16 100644 --- a/site/user/sample/viewer.md +++ b/site/user/sample/viewer.md @@ -49,4 +49,4 @@ Swiping left and right will switch slides, pinch-zoom will zoom in and out, and iOS --- -The viewer is not yet fully supported on iOS, but can be used to display individual slides on a device by launching via `ios-deploy` with the `--match` or `--slide` command-line options. +The viewer is not yet fully supported on iOS, but can be used to display individual slides on a device by launching via `ios-deploy` with the `--match` or `--slide` command-line options. The viewer will automatically bundle the `resources` directory in the top-level Skia directory, and will bundle an `skps` directory if also placed in the Skia directory. diff --git a/src/ports/SkOSFile_ios.h b/src/ports/SkOSFile_ios.h new file mode 100644 index 0000000000..d74aa200cc --- /dev/null +++ b/src/ports/SkOSFile_ios.h @@ -0,0 +1,41 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkString.h" + +#ifdef SK_BUILD_FOR_IOS +#import <CoreFoundation/CoreFoundation.h> + +static bool ios_get_path_in_bundle(const char path[], SkString* result) { + // Get a reference to the main bundle + CFBundleRef mainBundle = CFBundleGetMainBundle(); + + // Get a reference to the file's URL + CFStringRef pathRef = CFStringCreateWithCString(nullptr, path, kCFStringEncodingUTF8); + // We use "data" as our subdirectory to match {{bundle_resources_dir}}/data in GN + // Unfortunately "resources" is not a valid top-level name in iOS, so we push it one level down + CFURLRef imageURL = CFBundleCopyResourceURL(mainBundle, pathRef, nullptr, CFSTR("data")); + CFRelease(pathRef); + if (!imageURL) { + return false; + } + if (!result) { + return true; + } + + // Convert the URL reference into a string reference + CFStringRef imagePath = CFURLCopyFileSystemPath(imageURL, kCFURLPOSIXPathStyle); + CFRelease(imageURL); + + // Get the system encoding method + CFStringEncoding encodingMethod = CFStringGetSystemEncoding(); + + // Convert the string reference into an SkString + result->set(CFStringGetCStringPtr(imagePath, encodingMethod)); + return true; +} +#endif diff --git a/src/ports/SkOSFile_posix.cpp b/src/ports/SkOSFile_posix.cpp index 448a5c8c9f..1985607ac7 100644 --- a/src/ports/SkOSFile_posix.cpp +++ b/src/ports/SkOSFile_posix.cpp @@ -19,6 +19,10 @@ #include <sys/types.h> #include <unistd.h> +#ifdef SK_BUILD_FOR_IOS +#include "SkOSFile_ios.h" +#endif + bool sk_exists(const char *path, SkFILE_Flags flags) { int mode = F_OK; if (flags & kRead_SkFILE_Flag) { @@ -27,7 +31,16 @@ bool sk_exists(const char *path, SkFILE_Flags flags) { if (flags & kWrite_SkFILE_Flag) { mode |= W_OK; } +#ifdef SK_BUILD_FOR_IOS + // if the default path fails, check the bundle (but only if read-only) + if (0 == access(path, mode)) { + return true; + } else { + return (kRead_SkFILE_Flag == flags && ios_get_path_in_bundle(path, nullptr)); + } +#else return (0 == access(path, mode)); +#endif } typedef struct { @@ -137,10 +150,16 @@ void SkOSFile::Iter::reset(const char path[], const char suffix[]) { ::closedir(self.fDIR); self.fDIR = nullptr; } - self.fPath.set(path); + if (path) { self.fDIR = ::opendir(path); +#ifdef SK_BUILD_FOR_IOS + // check bundle for directory + if (!self.fDIR && ios_get_path_in_bundle(path, &self.fPath)) { + self.fDIR = ::opendir(path); + } +#endif self.fSuffix.set(suffix); } else { self.fSuffix.reset(); diff --git a/src/ports/SkOSFile_stdio.cpp b/src/ports/SkOSFile_stdio.cpp index 501d275c0f..7cdc549df6 100644 --- a/src/ports/SkOSFile_stdio.cpp +++ b/src/ports/SkOSFile_stdio.cpp @@ -22,36 +22,9 @@ #endif #ifdef SK_BUILD_FOR_IOS -#import <CoreFoundation/CoreFoundation.h> - -static FILE* ios_open_from_bundle(const char path[], const char* perm) { - // Get a reference to the main bundle - CFBundleRef mainBundle = CFBundleGetMainBundle(); - - // Get a reference to the file's URL - CFStringRef pathRef = CFStringCreateWithCString(nullptr, path, kCFStringEncodingUTF8); - CFURLRef imageURL = CFBundleCopyResourceURL(mainBundle, pathRef, nullptr, nullptr); - CFRelease(pathRef); - if (!imageURL) { - return nullptr; - } - - // Convert the URL reference into a string reference - CFStringRef imagePath = CFURLCopyFileSystemPath(imageURL, kCFURLPOSIXPathStyle); - CFRelease(imageURL); - - // Get the system encoding method - CFStringEncoding encodingMethod = CFStringGetSystemEncoding(); - - // Convert the string reference into a C string - const char *finalPath = CFStringGetCStringPtr(imagePath, encodingMethod); - FILE* fileHandle = fopen(finalPath, perm); - CFRelease(imagePath); - return fileHandle; -} +#include "SkOSFile_ios.h" #endif - FILE* sk_fopen(const char path[], SkFILE_Flags flags) { char perm[4]; char* p = perm; @@ -68,18 +41,17 @@ FILE* sk_fopen(const char path[], SkFILE_Flags flags) { //TODO: on Windows fopen is just ASCII or the current code page, //convert to utf16 and use _wfopen FILE* file = nullptr; + file = fopen(path, perm); #ifdef SK_BUILD_FOR_IOS - // if read-only, try to open from bundle first - if (kRead_SkFILE_Flag == flags) { - file = ios_open_from_bundle(path, perm); - } - // otherwise just read from the Documents directory (default) - if (!file) { -#endif - file = fopen(path, perm); -#ifdef SK_BUILD_FOR_IOS + // if not found in default path and read-only, try to open from bundle + if (!file && kRead_SkFILE_Flag == flags) { + SkString bundlePath; + if (ios_get_path_in_bundle(path, &bundlePath)) { + file = fopen(bundlePath.c_str(), perm); + } } #endif + if (nullptr == file && (flags & kWrite_SkFILE_Flag)) { SkDEBUGF(("sk_fopen: fopen(\"%s\", \"%s\") returned nullptr (errno:%d): %s\n", path, perm, errno, strerror(errno))); @@ -140,7 +112,17 @@ void sk_fclose(FILE* f) { bool sk_isdir(const char *path) { struct stat status; if (0 != stat(path, &status)) { +#ifdef SK_BUILD_FOR_IOS + // check the bundle directory if not in default path + SkString bundlePath; + if (ios_get_path_in_bundle(path, &bundlePath)) { + if (0 != stat(bundlePath.c_str(), &status)) { + return false; + } + } +#else return false; +#endif } return SkToBool(status.st_mode & S_IFDIR); } |