void MCS_loadurl(MCObject *p_object, const char *p_url, const char *p_message) { bool t_success = true; MCSLoadUrlState *t_state = nil; char *t_processed = nil; MCNameRef t_message = nil; t_success = MCMemoryNew(t_state) && MCSystemProcessUrl(p_url, kMCSystemUrlOperationStrip, t_processed) && MCNameCreateWithCString(p_message, t_message); if (t_success) { t_state->url = t_processed; t_state->message = t_message; t_state->status = kMCSystemUrlStatusNone; t_state->object = p_object -> gethandle(); t_state->data . bytes = nil; t_state->data . size = 0; t_success = MCSystemLoadUrl(t_processed, MCS_loadurl_callback, t_state); } if (t_success) MCresult->clear(); else { MCCStringFree(t_processed); MCNameDelete(t_message); MCMemoryDelete(t_state); MCurlresult -> clear(); MCresult->sets("error: load URL failed"); } }
bool __MCValueCreate(MCValueTypeCode p_type_code, size_t p_size, __MCValue*& r_value) { void *t_value; // MW-2014-03-21: [[ Faster ]] If we are pooling this typecode, and the // pool isn't empty grab the ptr from there. if (p_type_code <= kMCValueTypeCodeList && s_value_pools[p_type_code] . count > 0) { t_value = s_value_pools[p_type_code] . values; s_value_pools[p_type_code] . count -= 1; s_value_pools[p_type_code] . values = *(__MCValue **)t_value; MCMemoryClear(t_value, p_size); } else { if (!MCMemoryNew(p_size, t_value)) return false; } __MCValue *self = (__MCValue *)t_value; self -> references = 1; self -> flags = (p_type_code << 28); r_value = self; return true; }
bool MCGImageCreateWithSkBitmap(const SkBitmap &p_bitmap, MCGImageRef &r_image) { bool t_success; t_success = true; __MCGImage *t_image; t_image = nil; if (t_success) t_success = MCMemoryNew(t_image); SkBitmap *t_bitmap; t_bitmap = nil; if (t_success) { t_bitmap = new SkBitmap(p_bitmap); t_bitmap -> lockPixels(); t_success = nil != t_bitmap; } if (t_success) { t_image -> bitmap = t_bitmap; t_image -> is_valid = true; t_image -> references = 1; r_image = t_image; } else { if (t_bitmap != nil) delete t_bitmap; MCMemoryDelete(t_image); } return t_success; }
bool MCPatternCreate(MCGImageRef p_image, MCGFloat p_scale, MCPatternRef &r_pattern) { bool t_success; t_success = true; MCPatternRef t_pattern; t_pattern = nil; t_success = MCMemoryNew(t_pattern); if (t_success) { t_pattern -> image = MCGImageRetain(p_image); t_pattern -> scale = p_scale; t_pattern -> references = 1; r_pattern = t_pattern; } else { MCMemoryDelete(t_pattern); } return t_success; }
void MCSystemRequestUserAttention(void) { if (s_bounce_nmr != nil) MCSystemCancelRequestUserAttention(); bool t_success; t_success = true; if (t_success) t_success = MCMemoryNew(s_bounce_nmr); if (t_success) { s_bounce_nmr -> nmMark = 1; s_bounce_nmr -> qType = nmType; if (NMInstall(s_bounce_nmr) != noErr) t_success = false; } if (!t_success) { MCMemoryDelete(s_bounce_nmr); s_bounce_nmr = nil; } }
void *android_font_create(const char *name, uint32_t size, bool bold, bool italic) { MCAndroidFont *t_font = nil; if (MCMemoryNew(t_font)) { SkTypeface::Style t_style = SkTypeface::kNormal; if (bold) { if (italic) t_style = SkTypeface::kBoldItalic; else t_style = SkTypeface::kBold; } else if (italic) t_style = SkTypeface::kItalic; // MM-2012-03-06: Check to see if we have a custom font of the given style and name available if (!create_skia_font_face_from_custom_font_name_and_style(name, bold, italic, t_font->sk_typeface)) t_font->sk_typeface = SkTypeface::CreateFromName(name, t_style); MCAssert(t_font->sk_typeface != NULL); t_font->size = size; } return t_font; }
static bool MCTextLayoutFontFromHFONT(void *p_font, MCTextLayoutFont*& r_font) { bool t_success; t_success = true; // First fetch the HFONT's LOGFONT structure LOGFONTA t_logfont; if (t_success) if (!GetObjectA(p_font, sizeof(LOGFONTA), &t_logfont)) t_success = false; if (t_success) t_logfont . lfHeight = -256; // Now use this to search for an existing layout font MCTextLayoutFont *self; self = nil; if (t_success) { self = MCTextLayoutFontFind(t_logfont); if (self != nil) { r_font = self; return true; } } // Otherwise we must go ahead and create a new font if (t_success) t_success = MCMemoryNew(self); if (t_success) { self -> handle = CreateFontIndirectA(&t_logfont); if (self -> handle == nil) t_success = false; } if (t_success) { MCListPushFront(s_fonts, self); self -> info = t_logfont; // Now see if the font is a linked font for(MCTextLayoutLinkedFont *t_links = s_linked_fonts; t_links != nil; t_links = t_links -> next) if (MCCStringEqualCaseless(t_links -> name, self -> info . lfFaceName)) { self -> linking = t_links; break; } r_font = self; } else MCTextLayoutFontDestroy(self); return t_success; }
// MW-2011-09-13: [[ Masks ]] Updated to store data in an MCWindowMask struct. MCWindowShape *MCImage::makewindowshape(void) { bool t_success = true; MCWindowShape *t_mask = nil; CGImageRef t_mask_image = nil; MCImageBitmap *t_bitmap = nil; uint8_t *t_alpha = nil; uindex_t t_alpha_stride = 0; uindex_t t_width, t_height; t_success = lockbitmap(t_bitmap, true); if (t_success) t_success = MCImageBitmapHasTransparency(t_bitmap); if (t_success) { t_width = t_bitmap->width; t_height = t_bitmap->height; t_alpha_stride = (t_width + 3) & ~3; t_success = MCMemoryAllocate(t_alpha_stride * t_height, t_alpha); } if (t_success) { surface_extract_alpha(t_bitmap->data, t_bitmap->stride, t_alpha, t_alpha_stride, t_width, t_height); t_success = MCAlphaToCGImage(t_width, t_height, t_alpha, t_alpha_stride, t_mask_image); } if (t_success) t_success = MCMemoryNew(t_mask); unlockbitmap(t_bitmap); if (!t_success) { CGImageRelease(t_mask_image); MCMemoryDeallocate(t_mask); MCMemoryDeallocate(t_alpha); return nil; } t_mask->width = t_width; t_mask->height = t_height; t_mask->is_sharp = false; t_mask->data = (char*)t_alpha; t_mask->stride = t_alpha_stride; t_mask->handle = t_mask_image; return t_mask; }
bool MCAndroidStartTrackingHeading(bool p_loosely) { bool t_success = true; if (s_heading_reading == nil) t_success = MCMemoryNew(s_heading_reading); if (t_success) MCAndroidEngineRemoteCall("startTrackingHeading", "bb", &t_success, p_loosely); return t_success; }
inline bool MCMatrixNew(integer_t p_rows, integer_t p_cols, integer_t p_row_offset, integer_t p_col_offset, matrix_t*& r_matrix) { if (!MCMemoryNew(sizeof(matrix_t) + sizeof(real64_t) * p_rows * p_cols, (void*&)r_matrix)) return false; r_matrix->columns = p_cols; r_matrix->column_offset = p_col_offset; r_matrix->rows = p_rows; r_matrix->row_offset = p_row_offset; return true; }
bool MCSessionCreateSession(MCSessionIndexRef p_index, MCStringRef p_session_id, MCSession *&r_session) { bool t_success = true; MCSession *t_session = NULL; MCAutoStringRef t_remote_addr_string; char *t_remote_addr; t_remote_addr = NULL; if (MCS_getenv(MCSTR("REMOTE_ADDR"), &t_remote_addr_string)) MCCStringClone(MCStringGetCString(*t_remote_addr_string), t_remote_addr); t_success = MCMemoryNew(t_session); if (t_success) t_success = MCCStringClone(t_remote_addr ? t_remote_addr : "", t_session->ip); if (t_success) { if (p_session_id != nil && !MCStringIsEmpty(p_session_id)) { t_session->id = strdup(MCStringGetCString(p_session_id)); t_success = true; } else { MCAutoStringRef t_session_id; t_success = MCSessionGenerateID(&t_session_id); t_session->id = strdup(MCStringGetCString(*t_session_id)); } } if (t_success) t_success = MCCStringFormat(t_session->filename, "%s_%s", t_remote_addr ? t_remote_addr : "", t_session->id); if (t_success) t_success = MCSessionIndexAddSession(p_index, t_session); if (t_success) r_session = t_session; else { if (t_session != NULL) MCSessionCloseSession(t_session, false); } return t_success; }
JNIEXPORT void JNICALL Java_com_runrev_android_Engine_doRotationRateChanged(JNIEnv *env, jobject object, jfloat x, jfloat y, jfloat z, jfloat timestamp) { // MM-2012-03-13: Create first reading value only when we get a callback. // This means we can properly handle the case where the user requests a reading before one has been taken. if (s_rotation_rate_reading == nil) if (!MCMemoryNew(s_rotation_rate_reading)) return; s_rotation_rate_reading->x = x; s_rotation_rate_reading->y = y; s_rotation_rate_reading->z = z; s_rotation_rate_reading->timestamp = timestamp; MCSensorPostChangeMessage(kMCSensorTypeRotationRate); }
// TD-2013-07-02: [[ DynamicFonts ]] // MERG-2013-08-14: [[ DynamicFonts ]] Refactored to use MCLoadedFont bool MCFontLoad(MCStringRef p_path, bool p_globally) { bool t_success; t_success = true; if (t_success) { // check if already loaded and unload if globally is not the same as loaded version for(MCLoadedFont *t_font = s_loaded_fonts; t_font != nil; t_font = t_font -> next) if (MCStringIsEqualTo(t_font -> path, p_path, kMCStringOptionCompareCaseless)) { if (t_font -> is_global != p_globally) { t_success = MCFontUnload(p_path); break; } else return true; } } if (t_success) { void * t_loaded_font_handle; if (!MCscreen -> loadfont(p_path, p_globally, t_loaded_font_handle)) return false; MCLoadedFontRef self; if (!MCMemoryNew(self)) return false; self -> is_global = p_globally; self -> handle = t_loaded_font_handle; MCValueAssign(self -> path, p_path); self -> next = s_loaded_fonts; s_loaded_fonts = self; // MW-2013-09-11: [[ DynamicFonts ]] Make sure the engine reloads all fonts. MCFontRemap(); MCstacks -> purgefonts(); } return t_success; }
bool storeURLInfo(const char *p_url, MCSystemUrlCallback p_callback, void *p_context, MCUrlInfo *&r_info) { bool t_success = true; MCUrlInfo *t_info = nil; t_success = MCMemoryNew(t_info); if (t_success) t_success = MCCStringClone(p_url, t_info->url); if (t_success) { t_info->callback = p_callback; t_info->context = p_context; if (s_urlinfo_list == nil) { s_urlinfo_list = t_info; t_info->id = 1; } else { uint32_t t_id = s_urlinfo_list->id + 1; MCUrlInfo *t_list = s_urlinfo_list; while (t_list->next != NULL && t_list->next->id == t_id) { t_list = t_list->next; t_id++; } t_info->next = t_list->next; t_list->next = t_info; t_info->id = t_id; } } if (t_success) r_info = t_info; else { if (t_info != nil) MCCStringFree(t_info->url); MCMemoryDelete(t_info); } return t_success; }
// TD-2013-07-02: [[ DynamicFonts ]] // MERG-2013-08-14: [[ DynamicFonts ]] Refactored to use MCLoadedFont Exec_stat MCFontLoad(MCExecPoint& ep, const char *p_path, bool p_globally) { Exec_stat t_stat; t_stat = ES_NORMAL; if (t_stat == ES_NORMAL) { // check if already loaded and unload if globally is not the same as loaded version for(MCLoadedFont *t_font = s_loaded_fonts; t_font != nil; t_font = t_font -> next) if (MCU_strcasecmp(t_font -> path, p_path) == 0) { if (t_font -> is_global != p_globally) { t_stat = MCFontUnload(ep,p_path); break; } else return ES_NORMAL; } } if (t_stat == ES_NORMAL) { void * t_loaded_font_handle; if (!MCscreen -> loadfont(p_path, p_globally, t_loaded_font_handle)) return ES_ERROR; MCLoadedFontRef self; if (!MCMemoryNew(self)) return ES_ERROR; self -> is_global = p_globally; self -> handle = t_loaded_font_handle; self -> path = strdup(p_path); self -> next = s_loaded_fonts; s_loaded_fonts = self; // MW-2013-09-11: [[ DynamicFonts ]] Make sure the engine reloads all fonts. MCFontRemap(); MCstacks -> purgefonts(); } return t_stat; }
bool MCGRegionCreate(MCGRegionRef &r_region) { bool t_success; t_success = true; MCGRegionRef t_region; t_region = nil; if (t_success) t_success = MCMemoryNew(t_region); if (t_success) r_region = t_region; else MCGRegionDestroy(t_region); return t_success; }
JNIEXPORT void JNICALL JNICALL Java_com_runrev_android_Engine_doHeadingChanged(JNIEnv *env, jobject object, jdouble heading, jdouble magnetic_heading, jdouble true_heading, jfloat timestamp, jfloat x, jfloat y, jfloat z, jfloat accuracy) { // MM-2012-03-13: Create first reading value only when we get a callback. // This means we can properly handle the case where the user requests a reading before one has been taken. if (s_heading_reading == nil) if (!MCMemoryNew(s_heading_reading)) return; s_heading_reading->heading = heading; s_heading_reading->magnetic_heading = magnetic_heading; s_heading_reading->true_heading = true_heading; s_heading_reading->timestamp = timestamp; s_heading_reading->x = x; s_heading_reading->y = y; s_heading_reading->z = z; s_heading_reading->accuracy = accuracy; MCSensorPostChangeMessage(kMCSensorTypeHeading); }
bool MCSessionReadIndex(MCSessionIndexRef p_index) { bool t_success = true; t_success = read_uint32(p_index->file, p_index->session_count); if (t_success) t_success = MCMemoryNewArray(p_index->session_count, p_index->session); for (uint32_t i = 0; t_success && i < p_index->session_count; i++) { t_success = MCMemoryNew(p_index->session[i]); if (t_success) t_success = read_cstring(p_index->file, p_index->session[i]->id) && read_cstring(p_index->file, p_index->session[i]->ip) && read_cstring(p_index->file, p_index->session[i]->filename) && read_real64(p_index->file, p_index->session[i]->expires); } return t_success; }
JNIEXPORT void JNICALL Java_com_runrev_android_Engine_doLocationChanged(JNIEnv *env, jobject object, jdouble latitude, jdouble longitude, jdouble altitude, jfloat timestamp, jfloat accuracy, jdouble speed, jdouble course) { // MM-2012-03-13: Create first reading value only when we get a callback. // This means we can properly handle the case where the user requests a reading before one has been taken. if (s_location_reading == nil) if (!MCMemoryNew(s_location_reading)) return; s_location_reading->latitude = latitude; s_location_reading->longitude = longitude; s_location_reading->altitude = altitude; s_location_reading->timestamp = timestamp; s_location_reading->horizontal_accuracy = accuracy; s_location_reading->vertical_accuracy = 0; // MM-2013-02-21: Added speed and course to location sensor readings. s_location_reading->speed = speed; s_location_reading->course = course; MCSensorPostChangeMessage(kMCSensorTypeLocation); }
bool MCTileCacheSoftwareCompositorConfigure(MCTileCacheRef p_tilecache, MCTileCacheCompositor& r_compositor) { MCTileCacheSoftwareCompositorContext *t_context; if (!MCMemoryNew(t_context)) return false; t_context -> tilecache = p_tilecache; r_compositor . context = t_context; r_compositor . cleanup = MCTileCacheSoftwareCompositor_Cleanup; r_compositor . allocate_tile = MCTileCacheSoftwareCompositor_AllocateTile; r_compositor . deallocate_tile = MCTileCacheSoftwareCompositor_DeallocateTile; r_compositor . begin_frame = MCTileCacheSoftwareCompositor_BeginFrame; r_compositor . end_frame = MCTileCacheSoftwareCompositor_EndFrame; r_compositor . begin_layer = MCTileCacheSoftwareCompositor_BeginLayer; r_compositor . end_layer = MCTileCacheSoftwareCompositor_EndLayer; r_compositor . composite_tile = MCTileCacheSoftwareCompositor_CompositeTile; r_compositor . composite_rect = MCTileCacheSoftwareCompositor_CompositeRect; return true; }
bool MCTileCacheCoreGraphicsCompositorConfigure(MCTileCacheRef p_tilecache, MCTileCacheCompositor& r_compositor) { MCTileCacheCoreGraphicsCompositorContext *t_context; if (!MCMemoryNew(t_context)) return false; t_context -> tilecache = p_tilecache; /* UNCHECKED */ MCImageGetCGColorSpace(t_context -> colorspace); r_compositor . context = t_context; r_compositor . cleanup = MCTileCacheCoreGraphicsCompositor_Cleanup; r_compositor . allocate_tile = MCTileCacheCoreGraphicsCompositor_AllocateTile; r_compositor . deallocate_tile = MCTileCacheCoreGraphicsCompositor_DeallocateTile; r_compositor . begin_frame = MCTileCacheCoreGraphicsCompositor_BeginFrame; r_compositor . end_frame = MCTileCacheCoreGraphicsCompositor_EndFrame; r_compositor . begin_layer = MCTileCacheCoreGraphicsCompositor_BeginLayer; r_compositor . end_layer = MCTileCacheCoreGraphicsCompositor_EndLayer; r_compositor . composite_tile = MCTileCacheCoreGraphicsCompositor_CompositeTile; r_compositor . composite_rect = MCTileCacheCoreGraphicsCompositor_CompositeRect; return true; }
bool MCSessionOpenIndex(MCSessionIndexRef &r_index) { bool t_success = true; MCSessionIndexRef t_index = nil; t_success = MCMemoryNew(t_index); MCAutoStringRef t_save_path; if (t_success) t_success = MCS_get_session_save_path(&t_save_path); if (t_success) t_success = MCStringCopy(*t_save_path, t_index->save_path); MCAutoStringRef t_path_string; if (t_success) t_success = MCStringFormat(&t_path_string, "%@/lcsessions.idx", t_index->save_path); // open file if (t_success) t_success = NULL != (t_index->file = MCsystem->OpenFile(*t_path_string, kMCOpenFileModeUpdate, false)); // lock file if (t_success) t_success = MCSystemLockFile(t_index->file, false, true); // read index if (t_success && t_index->file->GetFileSize() > 0) t_success = MCSessionReadIndex(t_index); if (t_success) r_index = t_index; else MCSessionCloseIndex(t_index, false); return t_success; }
bool MCFiberCreate(size_t p_stack_size, MCFiberRef& r_fiber) { MCFiberRef self; if (!MCMemoryNew(self)) return false; if (s_fibers == nil) MCFiberInitialize(); self -> thread = nil; self -> next = s_fibers; s_fibers = self; if (pthread_create(&self -> thread, nil, MCFiberOwnedThreadRoutine, self) != 0) { MCFiberDestroy(self); return false; } r_fiber = self; return true; }
bool MCFiberConvert(MCFiberRef& r_fiber) { MCFiberRef self; if (!MCMemoryNew(self)) return false; // If we have no fibers already, initialize ourselves. if (s_fibers == nil) MCFiberInitialize(); // Get the thread id of the fiber and link it into the fiber chain. self -> thread = pthread_self(); self -> next = s_fibers; s_fibers = self; // As we are converting the current thread, the current fiber becomes // self. s_fiber_current = self; // Return successfully. r_fiber = self; return true; }
bool MCSessionCopySession(MCSession *p_src, MCSession *&r_dst) { bool t_success = true; MCSession *t_session; t_success = MCMemoryNew(t_session); if (t_success) t_success = MCCStringClone(p_src->id, t_session->id); if (t_success) t_success = MCCStringClone(p_src->ip, t_session->ip); if (t_success) t_success = MCCStringClone(p_src->filename, t_session->filename); if (t_success) t_session->expires = p_src->expires; if (t_success) r_dst = t_session; else MCSessionDisposeSession(t_session); return t_success; }
bool MCGCacheTableCreate(uindex_t p_size, uindex_t p_max_occupancy, uindex_t p_max_bytes, MCGCacheTableRef &r_cache_table) { bool t_success; t_success = true; __MCGCacheTable *t_cache_table; t_cache_table = NULL; if (t_success) t_success = MCMemoryNew(t_cache_table); __MCGCacheTableEntry *t_pairs; t_pairs = NULL; if (t_success) t_success = MCMemoryNewArray(p_size, t_pairs); if (t_success) { t_cache_table -> total_buckets = p_size; t_cache_table -> used_buckets = 0; t_cache_table -> max_occupancy = p_max_occupancy; t_cache_table -> max_bytes = p_max_bytes; t_cache_table -> bytes_used = sizeof(__MCGCacheTable) + sizeof(__MCGCacheTableEntry) * p_size; t_cache_table -> pairs = t_pairs; t_success = p_max_bytes > t_cache_table -> bytes_used; } if (t_success) r_cache_table = t_cache_table; else { MCMemoryDeleteArray(t_pairs); MCMemoryDelete(t_cache_table); } return t_success; }
bool MCPurchaseInit(MCPurchase *p_purchase, MCStringRef p_product_id, void *p_context) { bool t_success = true; if (p_context != nil) p_purchase->platform_data = p_context; else { MCAndroidPurchase *t_android_data = nil; t_success = MCStringGetLength(p_product_id) != 0; if (t_success) t_success = MCMemoryNew(t_android_data); if (t_success) t_android_data->product_id = MCValueRetain(p_product_id); if (t_success) p_purchase->platform_data = t_android_data; else MCMemoryDelete(t_android_data); } return t_success; }
static bool MCEventQueuePostAtFront(MCEventType p_type, MCEvent*& r_event) { MCEvent *t_event; if (!MCMemoryNew(t_event)) return false; if (s_first_event == nil) s_first_event = s_last_event = t_event; else { t_event -> next = s_first_event; s_first_event = t_event; } t_event -> type = p_type; // MW-2011-08-16: [[ Wait ]] Ping any running wait loop to make sure it // picks up the new event if it wants to. MCscreen -> pingwait(); r_event = t_event; return true; }
void MCGContextDrawPlatformText(MCGContextRef self, const unichar_t *p_text, uindex_t p_length, MCGPoint p_location, const MCGFont &p_font) { // MW-2013-12-19: [[ Bug 11559 ]] Do nothing if no text support. if (!s_has_text_support) return; if (!MCGContextIsValid(self)) return; bool t_success; t_success = true; if (t_success) t_success = s_layout != NULL; char *t_text; t_text = nil; if (t_success) t_success = MCCStringFromUnicodeSubstring(p_text, p_length / 2, t_text); MCGAffineTransform t_transform; MCGPoint t_device_location; PangoLayoutLine *t_line; t_line = nil; if (t_success) { t_transform = MCGContextGetDeviceTransform(self); t_device_location = MCGPointApplyAffineTransform(p_location, t_transform); t_transform . tx = modff(t_device_location . x, &t_device_location . x); t_transform . ty = modff(t_device_location . y, &t_device_location . y); PangoMatrix t_ptransform; t_ptransform . xx = t_transform . a; t_ptransform . xy = t_transform . b; t_ptransform . yx = t_transform . c; t_ptransform . yy = t_transform . d; t_ptransform . x0 = t_transform . tx; t_ptransform . y0 = t_transform . ty; pango_context_set_matrix(s_pango, &t_ptransform); pango_layout_set_font_description(s_layout, (PangoFontDescription *) p_font . fid); pango_layout_set_text(s_layout, t_text, -1); MCCStringFree(t_text); extern PangoLayoutLine *(*pango_layout_get_line_readonly_ptr)(PangoLayout *, int); if (pango_layout_get_line_readonly_ptr != nil) t_line = pango_layout_get_line_readonly_ptr(s_layout, 0); else t_line = pango_layout_get_line(s_layout, 0); t_success = t_line != nil; } MCGIntRectangle t_text_bounds, t_clipped_bounds; if (t_success) { PangoRectangle t_pbounds; pango_layout_line_get_extents(t_line, NULL, &t_pbounds); MCGRectangle t_float_text_bounds; t_float_text_bounds . origin . x = t_pbounds . x / PANGO_SCALE; t_float_text_bounds . origin . y = t_pbounds . y / PANGO_SCALE; t_float_text_bounds . size . width = t_pbounds . width / PANGO_SCALE; t_float_text_bounds . size . height = t_pbounds . height / PANGO_SCALE; MCGRectangle t_device_clip; t_device_clip = MCGContextGetDeviceClipBounds(self); t_device_clip . origin . x -= t_device_location . x; t_device_clip . origin . y -= t_device_location . y; MCGRectangle t_float_clipped_bounds; t_float_clipped_bounds = MCGRectangleIntersection(t_float_text_bounds, t_device_clip); t_text_bounds = MCGRectangleIntegerBounds(t_float_text_bounds); t_clipped_bounds = MCGRectangleIntegerBounds(t_float_clipped_bounds); if (t_clipped_bounds . width == 0 || t_clipped_bounds . height == 0) return; } void *t_data; t_data = nil; if (t_success) t_success = MCMemoryNew(t_clipped_bounds . width * t_clipped_bounds . height, t_data); if (t_success) { FT_Bitmap t_ftbitmap; t_ftbitmap . rows = t_clipped_bounds . height; t_ftbitmap . width = t_clipped_bounds . width; t_ftbitmap . pitch = t_clipped_bounds . width; t_ftbitmap . buffer = (unsigned char*) t_data; t_ftbitmap . num_grays = 256; t_ftbitmap . pixel_mode = FT_PIXEL_MODE_GRAY; t_ftbitmap . palette_mode = 0; t_ftbitmap . palette = nil; pango_ft2_render_layout_line(&t_ftbitmap, t_line, -(t_clipped_bounds . x - t_text_bounds . x), -(t_clipped_bounds . y - t_text_bounds . y) - t_text_bounds . y); SkPaint t_paint; t_paint . setStyle(SkPaint::kFill_Style); t_paint . setAntiAlias(self -> state -> should_antialias); t_paint . setColor(MCGColorToSkColor(self -> state -> fill_color)); SkXfermode *t_blend_mode; t_blend_mode = MCGBlendModeToSkXfermode(self -> state -> blend_mode); t_paint . setXfermode(t_blend_mode); if (t_blend_mode != NULL) t_blend_mode -> unref(); SkBitmap t_bitmap; t_bitmap . setConfig(SkBitmap::kA8_Config, t_clipped_bounds . width, t_clipped_bounds . height); t_bitmap . setIsOpaque(false); t_bitmap . setPixels(t_data); self -> layer -> canvas -> drawSprite(t_bitmap, t_clipped_bounds . x + t_device_location . x, t_clipped_bounds . y + t_device_location . y, &t_paint); } MCMemoryDelete(t_data); self -> is_valid = t_success; }
bool MCFontCreate(MCNameRef p_name, MCFontStyle p_style, int32_t p_size, MCFontRef& r_font) { for(MCFont *t_font = s_fonts; t_font != nil; t_font = t_font -> next) { if (p_name == t_font -> name && p_style == t_font -> style && p_size == t_font -> size) { t_font -> references += 1; r_font = t_font; return true; } } MCFontRef self; if (!MCMemoryNew(self)) return false; self -> references = 1; /* UNCHECKED */ MCNameClone(p_name, self -> name); self -> style = p_style; self -> size = p_size; uint2 t_temp_size; t_temp_size = self -> size; self -> fontstruct = MCdispatcher -> loadfont(self -> name, t_temp_size, MCFontStyleToTextStyle(self -> style), (self -> style & kMCFontStylePrinterMetrics) != 0); // MW-2013-12-04: [[ Bug 11535 ]] Test to see if the font is fixed-width, at least for // Roman script. MCGFont t_gfont; t_gfont = MCFontStructToMCGFont(self -> fontstruct); t_gfont . fixed_advance = 0; // We check the width of ' ', i, l, m and w. If they are all the same width // we assume the font is monospaced and subsequently set the fixed_advance // field to a suitable value. MCGFloat t_last_width; for(uindex_t i = 0; i < 5; i++) { unichar_t t_char; t_char = (unichar_t)((" ilmw")[i]); // MM-2014-04-16: [[ Bug 11964 ]] MCGContextMeasurePlatformText prototype updated to take scale. Pass identity. MCGFloat t_this_width; t_this_width = MCGContextMeasurePlatformText(nil, &t_char, 2, t_gfont, MCGAffineTransformMakeIdentity()); if (t_this_width == 0.0 || (i != 0 && t_this_width != t_last_width)) { t_last_width = 0; break; } t_last_width = t_this_width; } self -> fixed_advance = floorf(t_last_width + 0.5); self -> next = s_fonts; s_fonts = self; r_font = self; return true; }