void add_simulator_redirect(const char *p_redirect_def) { const char *t_dst_offset; t_dst_offset = strstr(p_redirect_def, "//"); if (t_dst_offset == nil) return; if (!MCMemoryResizeArray(s_redirect_count + 1, s_redirects, s_redirect_count)) return; if (s_redirect_base == nil) MCCStringCloneSubstring(MCcmd, strrchr(MCcmd, '/') - MCcmd, s_redirect_base); MCCStringCloneSubstring(p_redirect_def, t_dst_offset - p_redirect_def, s_redirects[s_redirect_count - 1] . src); // MW-2012-10-30: [[ Bug 10495 ]] Redirects are given to us in MacRoman, so convert to // UTF-8 (which the FS expects). MCCStringFromNative(t_dst_offset + 2, s_redirects[s_redirect_count - 1] . dst); }
bool MCSystemStripUrl(const char *p_url, char *&r_stripped) { uindex_t t_start = 0; uindex_t t_end = MCCStringLength(p_url); while (t_start < t_end && is_whitespace(p_url[t_start])) t_start++; while (t_end > t_start && is_whitespace(p_url[t_end - 1])) t_end--; return MCCStringCloneSubstring(p_url + t_start, t_end - t_start, r_stripped); }
bool MCImageSplitScaledFilename(const char *p_filename, char *&r_base, char *&r_extension, bool &r_has_scale, MCGFloat &r_scale) { if (p_filename == nil) return false; bool t_success; t_success = true; MCGFloat t_scale; bool t_has_scale = false; uint32_t t_length; t_length = MCCStringLength(p_filename); uint32_t t_index, t_name_start, t_label_start, t_label_search_start, t_ext_start; if (MCCStringLastIndexOf(p_filename, '/', t_index)) t_name_start = t_index + 1; else t_name_start = 0; if (MCCStringLastIndexOf(p_filename + t_name_start, '.', t_index)) t_ext_start = t_name_start + t_index; else t_ext_start = t_length; // find first '@' char before the extension part t_label_start = t_label_search_start = t_name_start; while (MCCStringFirstIndexOf(p_filename + t_label_search_start, '@', t_index)) { if (t_label_start + t_index > t_ext_start) break; t_label_start += t_index; t_label_search_start = t_label_start + 1; } // check label begins with '@' if (p_filename[t_label_start] != '@') { // no scale label t_label_start = t_ext_start; } else { t_has_scale = MCImageGetScaleForLabel(p_filename + t_label_start, t_ext_start - t_label_start, t_scale); if (!t_has_scale) { // @... is not a recognised scale t_label_start = t_ext_start; } } char *t_base, *t_extension; t_base = t_extension = nil; t_success = MCCStringCloneSubstring(p_filename, t_label_start, t_base) && MCCStringCloneSubstring(p_filename + t_ext_start, t_length - t_ext_start, t_extension); if (t_success) { r_base = t_base; r_extension = t_extension; r_has_scale = t_has_scale; r_scale = t_has_scale ? t_scale : 1.0; } else { MCCStringFree(t_base); MCCStringFree(t_extension); } return t_success; }
static bool create_custom_font_from_path(const char *p_path, FT_Library p_library, MCAndroidCustomFont *&r_custom_font) { bool t_success; t_success = true; char *t_buffer; t_buffer = nil; uint32_t t_file_size; t_file_size = 0; if (t_success) t_success = load_custom_font_file_into_buffer_from_path(p_path, t_buffer, t_file_size); FT_Face t_font_face; t_font_face = nil; if (t_success) t_success = FT_New_Memory_Face(p_library, (FT_Byte *)t_buffer, t_file_size, 0, &t_font_face) == 0; MCAndroidCustomFont *t_font; t_font = nil; if (t_success) t_success = MCMemoryNew(t_font); if (t_success) t_success = MCCStringClone(p_path, t_font->path); if (t_success) t_success = MCCStringClone(t_font_face->family_name, t_font->family); if (t_success) { if (MCCStringEqualCaseless(t_font_face->style_name, "bold")) t_font->style = kMCAndroidFontStyleBold; else if (MCCStringEqualCaseless(t_font_face->style_name, "italic")) t_font->style = kMCAndroidFontStyleItalic; else if (MCCStringEqualCaseless(t_font_face->style_name, "bold italic")) t_font->style = kMCAndroidFontStyleBoldItalic; else t_font->style = kMCAndroidFontStyleRegular; } if (t_success) { FT_SfntName t_sft_name; for (uint32_t i = 0; i < FT_Get_Sfnt_Name_Count(t_font_face); i++) { // Attempt to fetch the name of the font. The name is name id 4 as defined in https://developer.apple.com/fonts/TTRefMan/RM06/Chap6name.html // It appears that the platform to use here is 1 (Macintosh according to the spec). FT_Get_Sfnt_Name(t_font_face, i, &t_sft_name); if (t_sft_name.name_id == 4 && t_sft_name.platform_id == 1 && t_sft_name.encoding_id == 0 && t_sft_name.language_id == 0 && t_sft_name.string_len != 0) { t_success = MCCStringCloneSubstring((char *)t_sft_name.string, t_sft_name.string_len, t_font->name); break; } } } if (t_success) t_success = t_font->name != nil; if (t_success) r_custom_font = t_font; else delete_custom_font(t_font); if (t_font_face != nil) FT_Done_Face(t_font_face); /*UNCHECKED */ MCMemoryDelete(t_buffer); return t_success; }
static DIR* opendir_wrapper(const char *dirname) { char *t_resolved_path; compute_simulator_redirect(dirname, t_resolved_path); if (s_redirect_base != nil && MCCStringEqual(t_resolved_path, s_redirect_base)) { DIR *t_sys_dir; t_sys_dir = opendir_trampoline(t_resolved_path); if (t_sys_dir == nil) return nil; DIR_wrapper *t_wrapper; t_wrapper = (DIR_wrapper *)malloc(sizeof(DIR_wrapper)); t_wrapper -> fd = -t_sys_dir -> __dd_fd; t_wrapper -> sys_dir = t_sys_dir; t_wrapper -> entry_count = 0; t_wrapper -> entries = nil; t_wrapper -> index = 0; for(;;) { struct dirent *t_dir_entry; t_dir_entry = readdir(t_sys_dir); if (t_dir_entry == nil) break; MCMemoryResizeArray(t_wrapper -> entry_count + 1, t_wrapper -> entries, t_wrapper -> entry_count); MCCStringClone(t_dir_entry -> d_name, t_wrapper -> entries[t_wrapper -> entry_count - 1]); } for(uint32_t i = 0; i < s_redirect_count; i++) { const char *t_src, *t_src_end; t_src = s_redirects[i] . src; t_src_end = strchr(t_src, '/'); if (t_src_end == nil) t_src_end = t_src + strlen(t_src); bool t_found; t_found = false; for(uint32_t j = 0; j < t_wrapper -> entry_count; j++) if (strlen(t_wrapper -> entries[j]) == (t_src_end - t_src) && strncmp(t_wrapper -> entries[j], t_src, t_src_end - t_src) == 0) { t_found = true; break; } if (t_found) continue; MCMemoryResizeArray(t_wrapper -> entry_count + 1, t_wrapper -> entries, t_wrapper -> entry_count); MCCStringCloneSubstring(t_src, t_src_end - t_src, t_wrapper -> entries[t_wrapper -> entry_count - 1]); } return (DIR *)t_wrapper; } DIR *t_result; t_result = opendir_trampoline(t_resolved_path); if (t_resolved_path != dirname) free(t_resolved_path); return t_result; }