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; }
static void cgi_dispose_multipart_context(cgi_multipart_context_t *p_context) { MCCStringFree(p_context->name); MCCStringFree(p_context->file_name); MCCStringFree(p_context->type); MCCStringFree(p_context->boundary); if (p_context->file_handle != NULL) MCS_close(p_context->file_handle); MCMemoryClear(p_context, sizeof(cgi_multipart_context_t)); }
// MM-2011-03-24: Added. Displays a balloon popup above the taskbar icon containing the given message and title. void MCSystemBalloonNotification(MCStringRef p_title, MCStringRef p_message) { // Shell_NotifyIconA uses the cbSize of the struct passed to determine what fields have been set // allowing us to use the extended NOTIFYICONDATA500A struct with the extra fields for balloons. NOTIFYICONDATA500W t_nidata; MCMemoryClear(&t_nidata, sizeof(NOTIFYICONDATA500W)); t_nidata . cbSize = sizeof(NOTIFYICONDATA500W); // Fecth the window handle that we have bound the taskbar icon to. // Only one task bar icon has been created within this window hanlde, with ID 1. t_nidata . hWnd = ((MCScreenDC *)MCscreen) -> getinvisiblewindow(); t_nidata . uID = 1; // The NIF_INFO flag determines that the popup should be a balloon rather than a tooltip. // The NIIF_INFO flag determines that the info (little i) icon should be used in the balloon. t_nidata . uFlags = NIF_INFO; t_nidata . dwInfoFlags = NIIF_INFO; MCAutoStringRefAsWString t_title, t_message; // We can specify the title (appears in bold next to the icon) and the body of the balloon. if (p_title != nil) { t_title . Lock(p_title); MCMemoryCopy(t_nidata . szInfoTitle, *t_title, 63 * sizeof(WCHAR)); } else t_nidata . szInfoTitle[0] = '\0'; if (p_message != nil) { t_message . Lock(p_message); MCMemoryCopy(t_nidata . szInfo, *t_message, 255 * sizeof(WCHAR)); } else t_nidata . szInfo[0] = '\0'; // Call with NIM_MODIFY to flag that we want to update an existing taskbar icon. Shell_NotifyIconW(NIM_MODIFY, (PNOTIFYICONDATAW) &t_nidata); }
static bool cgi_store_form_multipart(MCExecPoint& ep, IO_handle p_stream) { bool t_success = true; char *t_boundary = NULL; cgi_multipart_context_t t_context; MCMemoryClear(&t_context, sizeof(t_context)); uint32_t t_bytes_read = 0; if (t_success) t_success = cgi_multipart_get_boundary(t_boundary); if (t_success) t_success = MCMultiPartReadMessageFromStream(p_stream, t_boundary, t_bytes_read, cgi_multipart_header_callback, cgi_multipart_body_callback, &t_context); // clean up in case of errors; if (!t_success) cgi_dispose_multipart_context(&t_context); MCCStringFree(t_boundary); return t_success; }
bool MCGImageImageRep::GetMetadata(MCImageMetadata &r_metadata) { MCMemoryClear(&r_metadata, sizeof(MCImageMetadata)); return true; }
bool MCImageEncodeGIF(MCImageIndexedBitmap *p_indexed, IO_handle p_stream, uindex_t &r_bytes_written) { bool t_success = true; int32_t t_transparent = -1; uindex_t t_palette_size; uindex_t t_depth; t_depth = GifBitSize(p_indexed->palette_size); // GIF requires palette size to be 2^depth t_palette_size = 1 << t_depth; int t_err = 0; GifFileType *t_gif = nil; ColorMapObject *t_colormap = nil; MCGIFWriteContext t_context; t_context.stream = p_stream; t_context.byte_count = 0; t_success = nil != (t_gif = EGifOpen(&t_context, gif_writeFunc, &t_err)); if (t_success) t_success = nil != (t_colormap = GifMakeMapObject(t_palette_size, nil)); if (t_success) { for (uindex_t i = 0; i < p_indexed->palette_size; i++) { t_colormap->Colors[i].Red = p_indexed->palette[i].red; t_colormap->Colors[i].Green = p_indexed->palette[i].green; t_colormap->Colors[i].Blue = p_indexed->palette[i].blue; } for (uindex_t i = p_indexed->palette_size; i < t_palette_size; i++) { t_colormap->Colors[i].Red = t_colormap->Colors[i].Green = t_colormap->Colors[i].Blue = 0; } if (MCImageIndexedBitmapHasTransparency(p_indexed)) { t_transparent = p_indexed->transparent_index; t_colormap->Colors[t_transparent].Red = t_colormap->Colors[t_transparent].Green = t_colormap->Colors[t_transparent].Blue = 0xFF; } t_success = GIF_OK == EGifPutScreenDesc(t_gif, p_indexed->width, p_indexed->height, t_depth, 0, t_colormap); } if (t_success) { if (t_transparent != -1) { GraphicsControlBlock t_gcb; MCMemoryClear(&t_gcb, sizeof(t_gcb)); t_gcb.TransparentColor = t_transparent; GifByteType t_extension[4]; uindex_t t_extension_size; t_extension_size = EGifGCBToExtension(&t_gcb, t_extension); // Should always be 4 bytes MCAssert(t_extension_size == sizeof(t_extension)); t_success = GIF_OK == EGifPutExtension(t_gif, GRAPHICS_EXT_FUNC_CODE, sizeof(t_extension), t_extension); } } if (t_success) t_success = GIF_OK == EGifPutImageDesc(t_gif, 0, 0, p_indexed->width, p_indexed->height, false, nil); for (uindex_t y = 0; t_success && y < p_indexed->height; y++) t_success = GIF_OK == EGifPutLine(t_gif, (uint8_t*)p_indexed->data + y * p_indexed->stride, p_indexed->width); int t_error_code; if (GIF_ERROR == EGifCloseFile(t_gif, &t_error_code)) t_success = false; GifFreeMapObject(t_colormap); if (t_success) r_bytes_written = t_context.byte_count; return t_success; }
bool MCTextLayout(const unichar_t *p_chars, uint32_t p_char_count, MCFontStruct *p_font, MCTextLayoutCallback p_callback, void *p_context) { bool t_success; t_success = true; // The state structure we use to record the list of runs and the dc we use // for processing. MCTextLayoutState self; MCMemoryClear(&self, sizeof(MCTextLayoutState)); if (t_success) { self . dc = CreateCompatibleDC(nil); if (self . dc == nil) t_success = false; } // Fetch a layout font for the provided HFONT. if (t_success) t_success = MCTextLayoutFontFromHFONT(p_font -> fid, self . primary_font); // First thing we need to do is itemize the input string. The ScriptItemize // function splits up the chars into runs, each run being potentially // processed differently by Uniscribe. // Unfortunately, there is no way to predict for an arbitrary string how // many items might be generated, nor is the ScriptItemize function // incremental, thus we must loop with an every increasing buffer until // we have enough room. SCRIPT_ITEM *t_items; uint32_t t_item_limit, t_item_count; SCRIPT_STATE t_script_state; SCRIPT_CONTROL t_script_control; t_items = nil; t_item_limit = 0; t_item_count = 0; MCMemoryClear(&t_script_state, sizeof(SCRIPT_STATE)); MCMemoryClear(&t_script_control, sizeof(SCRIPT_CONTROL)); while(t_success) { // Increase the item array by 32 each time if (t_success) t_success = MCMemoryResizeArray(t_item_limit + 32, t_items, t_item_limit); // Attempt to itemize HRESULT t_result; if (t_success) { t_result = ScriptItemize(p_chars, p_char_count, t_item_limit, &t_script_control, &t_script_state, t_items, (int *)&t_item_count); if (t_result != S_OK && t_result != E_OUTOFMEMORY) t_success = false; } if (t_success && t_result == S_OK) break; } // Next we loop through the items one by one, processing them as we go, this // process is slightly recursive - LayoutItem may recurse to fill in any // 'holes' caused by glyphs not in the primary font. for(uint32_t i = 0; i < t_item_count && t_success; i++) t_success = MCTextLayoutStyleItem( self, t_items[i] . a, p_chars + t_items[i] . iCharPos, t_items[i + 1] . iCharPos - t_items[i] . iCharPos, self . primary_font); // At this point we should have an array of runs to render. First though we // need to compute the visual to logical mapping. uint8_t *t_levels; int *t_map; t_levels = nil; t_map = nil; if (t_success) t_success = MCMemoryNewArray(self . run_count, t_levels) && MCMemoryNewArray(self . run_count, t_map); // Work out the run mapping, but only if we have runs to map! if (t_success && self . run_count > 0) { for(uint32_t i = 0; i < self . run_count; i++) t_levels[i] = self . runs[i] . embedding_level; if (ScriptLayout(self . run_count, t_levels, t_map, nil) != S_OK) t_success = false; } // Now we have the mapping we loop through the runs in the correct order // dispatching them to the callback. if (t_success && p_callback != nil) { double t_x; t_x = 0.0; for(uint32_t i = 0; i < self . run_count && t_success; i++) { MCTextLayoutRun *t_run; t_run = &self . runs[t_map[i]]; // Allocate a temporary array for the glyph structures MCTextLayoutGlyph *t_glyphs; t_glyphs = nil; if (t_success) t_success = MCMemoryNewArray(t_run -> glyph_count, t_glyphs); if (t_success) { // Compute the position for each glyph, keeping a running // total of the advance width. for(uint32_t i = 0; i < t_run -> glyph_count; i++) { t_glyphs[i] . index = t_run -> glyphs[i]; t_glyphs[i] . x = t_x + t_run -> goffsets[i] . du; t_glyphs[i] . y = t_run -> goffsets[i] . dv; t_x += t_run -> advances[i]; } // Dispatch the span to the callback. MCTextLayoutSpan t_span; t_span . chars = t_run -> chars; t_span . clusters = t_run -> clusters; t_span . char_count = t_run -> char_count; t_span . glyphs = t_glyphs; t_span . glyph_count = t_run -> glyph_count; t_span . font = t_run -> font -> handle; t_success = p_callback(p_context, &t_span); } // Free the temporary array. MCMemoryDeleteArray(t_glyphs); } } // Free all the arrays and other resources that have been allocated. MCMemoryDeleteArray(t_map); MCMemoryDeleteArray(t_levels); for(uint32_t i = 0; i < self . run_count; i++) { MCMemoryDeallocate(self . runs[i] . chars); MCMemoryDeallocate(self . runs[i] . clusters); MCMemoryDeallocate(self . runs[i] . glyphs); MCMemoryDeallocate(self . runs[i] . advances); MCMemoryDeallocate(self . runs[i] . goffsets); } MCMemoryDeleteArray(self . runs); MCMemoryDeleteArray(t_items); if (self . dc != nil) DeleteDC(self . dc); return t_success; }
static bool MCTextLayoutStyleItem(MCTextLayoutState& self, SCRIPT_ANALYSIS p_analysis, const unichar_t *p_chars, uint32_t p_char_count, MCTextLayoutFont *p_primary_font) { bool t_success; t_success = true; // Create a metafile dc into which we render the text HDC t_metafile_dc; t_metafile_dc = nil; if (t_success) { t_metafile_dc = CreateEnhMetaFile(nil, nil, nil, nil); if (t_metafile_dc == nil) t_success = false; } // Choose the primary font if (t_success) SelectObject(t_metafile_dc, p_primary_font -> handle); // Now use ScriptStringAnalyse to output the text into the metafile. SCRIPT_STRING_ANALYSIS t_ssa; t_ssa = nil; if (t_success) { SCRIPT_STATE t_script_state; SCRIPT_CONTROL t_script_control; MCMemoryClear(&t_script_state, sizeof(SCRIPT_STATE)); MCMemoryClear(&t_script_control, sizeof(SCRIPT_CONTROL)); if (ScriptStringAnalyse(t_metafile_dc, p_chars, p_char_count, 0, -1, SSA_METAFILE | SSA_FALLBACK | SSA_GLYPHS | SSA_LINK, 0, &t_script_control, &t_script_state, nil, nil, nil, &t_ssa) != S_OK) t_success = false; } // Render the analysed text into the metafile. if (t_success) if (ScriptStringOut(t_ssa, 0, 0, 0, nil, 0, 0, FALSE) != S_OK) t_success = false; // Fetch the metafile (we are done with the DC now) HENHMETAFILE t_metafile; t_metafile = nil; if (t_metafile_dc != nil) { t_metafile = CloseEnhMetaFile(t_metafile_dc); if (t_metafile == nil) t_success = false; } // Now process the metafile to get the subranges of text styled to the // appropriate fallback font. if (t_success) { MCTextLayoutStyleItemContext t_context; t_context . state = &self; t_context . chars = p_chars; t_context . char_count = p_char_count; t_context . analysis = p_analysis; t_context . primary_font = p_primary_font; t_context . current_font = p_primary_font; t_context . pending_x = 0; t_context . pending_font = nil; t_context . pending_chars = nil; t_context . pending_char_count = 0; if (!EnumEnhMetaFile(nil, t_metafile, MCTextLayoutStyleItemCallback, &t_context, nil)) t_success = false; } // Free the metafile if (t_metafile != nil) DeleteEnhMetaFile(t_metafile); return t_success; }