static bool MCS_loadurl_callback(void *p_context, MCSystemUrlStatus p_status, const void *p_data) { MCSLoadUrlState *context; context = static_cast<MCSLoadUrlState *>(p_context); context -> status = p_status; if (p_status == kMCSystemUrlStatusError) MCMemoryDelete(context->data.bytes); else if (p_status == kMCSystemUrlStatusLoading) { const MCString *t_data = static_cast<const MCString*>(p_data); MCMemoryReallocate(context->data.bytes, context->data.size + t_data->getlength(), context->data.bytes); MCMemoryCopy(static_cast<uint8_t*>(context->data.bytes) + context->data.size, t_data->getstring(), t_data->getlength()); context->data.size += t_data->getlength(); } send_url_progress(context -> object, p_status, context -> url, context -> data . size, context -> total, (const char *)p_data); if (p_status == kMCSystemUrlStatusError || p_status == kMCSystemUrlStatusFinished) { MCUrlLoadEvent *t_event; t_event = MCUrlLoadEvent::CreateUrlLoadEvent(context->object, context->message, context->url, p_status, context->data.bytes, context->data.size, static_cast<const char *>(p_data)); if (t_event) MCEventQueuePostCustom(t_event); context->object->Release(); MCCStringFree(context->url); MCNameDelete(context->message); MCMemoryDelete(context); } return true; }
static bool MCConvertNativeFromUTF16(const uint16_t *p_chars, uint32_t p_char_count, uint8_t*& r_output, uint32_t& r_output_length) { uint8_t *t_output; uint32_t t_output_length; if (!MCMemoryAllocate(p_char_count, t_output)) return false; uint32_t t_index; t_index = 0; t_output_length = 0; while(t_index < p_char_count) { if (p_chars[t_index] < 128 && (t_index == p_char_count - 1 || p_chars[t_index + 1] < 128)) { t_output[t_output_length++] = (char)p_chars[t_index]; t_index += 1; } else { uint32_t t_start; t_start = t_index; uint32_t t_codepoint; t_codepoint = MCUnicodeCodepointAdvance((const uint2 *)p_chars, p_char_count, t_index); while(t_index < p_char_count) { uint4 t_old_index; t_old_index = t_index; t_codepoint = MCUnicodeCodepointAdvance((const uint2 *)p_chars, p_char_count, t_index); if (MCUnicodeCodepointIsBase(t_codepoint)) { t_index = t_old_index; break; } } uint8_t t_char; if (!MCUnicodeMapToNative(p_chars + t_start, t_index - t_start, t_char)) t_char = '?'; t_output[t_output_length++] = t_char; } } MCMemoryReallocate(t_output, t_output_length, t_output); r_output = t_output; r_output_length = t_output_length; return true; }
bool rle_true_encode(const uint4 *sptr, uint4 ssize, uint1 *&dptr, uint4 &dsize) { uint4 osize = ssize + (ssize / 127); uint1 *destptr = nil; if (!MCMemoryNewArray(osize, destptr)) return false; const uint4 *eptr = sptr + ssize / sizeof(uint4); dsize = 0; uint2 run; do { run = 1; if (sptr < (eptr - 1) && *sptr == *(sptr + 1)) { uint4 pixel = *sptr; while (++sptr < eptr && *sptr == pixel && run < 127) run++; destptr[dsize++] = run | 0x80; swap_uint4(&pixel); memcpy(&destptr[dsize], &pixel, sizeof(uint4)); dsize += sizeof(uint4); } else { while (++sptr < (eptr - 1) && *sptr != *(sptr + 1) && run < 127) run++; destptr[dsize++] = (uint1)run; uint2 bytes = run * sizeof(uint4); memcpy(&destptr[dsize], sptr - run, bytes); uint4 *startptr = (uint32_t*)&destptr[dsize]; while (run--) swap_uint4(startptr++); dsize += bytes; } } while (sptr < eptr); if (!MCMemoryReallocate(destptr, dsize, dptr)) { MCMemoryDeleteArray(destptr); return false; } return true; }
bool serialize_bytes(char *&r_stream, uint32_t &r_stream_size, uint32_t &r_offset, const void *p_data, uint32_t p_data_size) { if (p_data_size == 0) return true; if (r_offset + p_data_size > r_stream_size) { char *t_stream; uint32_t t_size; t_size = r_offset + p_data_size; if (!MCMemoryReallocate(r_stream, t_size, t_stream)) return false; r_stream = t_stream; r_stream_size = t_size; } MCMemoryCopy(r_stream + r_offset, p_data, p_data_size); r_offset += p_data_size; return true; }
static bool MCTextLayoutPlaceItem(MCTextLayoutState& self, SCRIPT_ANALYSIS p_analysis, const unichar_t *p_chars, uint32_t p_char_count, const uint16_t *p_clusters, const uint16_t *p_glyphs, const SCRIPT_VISATTR *p_attrs, uint32_t p_glyph_count, MCTextLayoutFont *p_font) { bool t_success; t_success = true; MCTextLayoutRun *t_run; if (self . run_count != 0) t_run = &self . runs[self . run_count - 1]; else t_run = nil; // We need to append a new run if the font or embedding level has changed. if (t_run == nil || t_run -> font != p_font || t_run -> embedding_level != p_analysis . s . uBidiLevel) { if (self . run_count + 1 > self . run_limit) t_success = MCMemoryResizeArray(self . run_limit + 8, self . runs, self . run_limit); if (t_success) { t_run = &self . runs[self . run_count]; t_run -> font = p_font; t_run -> embedding_level = p_analysis . s . uBidiLevel; self . run_count += 1; } } // Allocate the cluster, glyph, goffset and advance arrays that we need. if (t_success) t_success = MCMemoryReallocate(t_run -> chars, (t_run -> char_count + p_char_count) * sizeof(unichar_t), t_run -> chars) && MCMemoryReallocate(t_run -> clusters, (t_run -> char_count + p_char_count) * sizeof(uint16_t), t_run -> clusters) && MCMemoryReallocate(t_run -> glyphs, (t_run -> glyph_count + p_glyph_count) * sizeof(uint16_t), t_run -> glyphs) && MCMemoryReallocate(t_run -> goffsets, (t_run -> glyph_count + p_glyph_count) * sizeof(GOFFSET), t_run -> goffsets) && MCMemoryReallocate(t_run -> advances, (t_run -> glyph_count + p_glyph_count) * sizeof(int), t_run -> advances); // Run the script placement method if (t_success) { SelectObject(self . dc, p_font -> handle); if (ScriptPlace( self . dc, &p_font -> cache, p_glyphs, p_glyph_count, p_attrs, &p_analysis, t_run -> advances + t_run -> glyph_count, t_run -> goffsets + t_run -> glyph_count, nil) != S_OK) t_success = false; } // Fill in the span structure if (t_success) { MCMemoryCopy(t_run -> chars + t_run -> char_count, p_chars, sizeof(unichar_t) * p_char_count); if ((p_analysis . s . uBidiLevel & 1) == 0) { MCMemoryCopy(t_run -> glyphs + t_run -> glyph_count, p_glyphs, sizeof(uint16_t) * p_glyph_count); MCMemoryCopy(t_run -> clusters + t_run -> char_count, p_clusters, sizeof(uint16_t) * p_char_count); } else { // In this case things are going Right to Left, so remap into visual order. for(uint32_t i = 0; i < p_char_count; i++) t_run -> clusters[i + t_run -> char_count] = p_glyph_count - p_clusters[i] - 1; for(uint32_t i = 0; i < p_glyph_count; i++) t_run -> glyphs[i + t_run -> glyph_count] = p_glyphs[p_glyph_count - i - 1]; for(uint32_t i = 0; i < p_glyph_count / 2; i++) { MCSwap(t_run -> advances[i + t_run -> glyph_count], t_run -> advances[t_run -> glyph_count + (p_glyph_count - i - 1)]); MCSwap(t_run -> goffsets[i + t_run -> glyph_count], t_run -> goffsets[t_run -> glyph_count + (p_glyph_count - i - 1)]); } } // As we might have elided a span, we need to shift all the cluster offsets up by the current // glyph count. for(uint32_t i = 0; i < p_char_count; i++) t_run -> clusters[i + t_run -> char_count] += t_run -> glyph_count; t_run -> char_count += p_char_count; t_run -> glyph_count += p_glyph_count; } return t_success; }