Beispiel #1
0
static bool MCTextLayoutFontWithLink(MCTextLayoutFont *p_base, MCTextLayoutLinkedFontEntry *p_link, MCTextLayoutFont*& r_font)
{
	LOGFONTA t_logfont;
	t_logfont = p_base -> info;
	MCMemoryCopy(&t_logfont . lfFaceName, p_link -> face, MCMax(MCCStringLength(p_link -> face) + 1, sizeof(t_logfont . lfFaceName)));

	MCTextLayoutFont *t_font;
	t_font = MCTextLayoutFontFind(t_logfont);
	if (t_font != nil)
	{
		r_font = t_font;
		return true;
	}
	
	HFONT t_hfont;
	t_hfont = CreateFontIndirectA(&t_logfont);
	if (t_hfont == nil)
		return false;

	bool t_success;
	t_success = MCTextLayoutFontFromHFONT(t_hfont, t_font);
	
	DeleteObject(t_hfont);

	r_font = t_font;

	return t_success;
}
Beispiel #2
0
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;
}
Beispiel #3
0
bool deserialize_data(const char *p_stream, uint32_t p_stream_size, uint32_t &r_offset, void *&r_data, uint32_t &r_size)
{
	uint32_t t_size = 0, t_data_size = 0;
	bool t_success = true;
	void *t_data = nil;
	t_success = deserialize_uint32(p_stream, p_stream_size, r_offset, t_data_size);
	if (t_success)
	{
		if (t_data_size == 0)
		{
			r_size = 0;
			return true;
		}
		if (r_data == nil)
		{
			t_size = t_data_size;
			MCMemoryAllocate(t_size, t_data);
		}
		else
		{
			t_size = r_size;
			t_data = r_data;
		}
		t_success = (t_data != nil && t_data_size <= t_size);
	}
	if (t_success)
	{
		MCMemoryCopy(t_data, p_stream + r_offset, t_data_size);
		r_data = t_data;
		r_size = t_size;
		r_offset += t_data_size;
	}
	return t_success;
}
Beispiel #4
0
bool MCStreamCache::ReadFromCache(void *p_buffer, uint32_t p_offset, uint32_t p_length, uint32_t &r_read)
{
	uint32_t t_to_read;
	if (m_cache_buffer != NULL)
	{
		r_read = MCMin(p_length, m_cache_length - p_offset);
		MCMemoryCopy(p_buffer, (uint8_t*)m_cache_buffer + p_offset, r_read);
		return true;
	}
	else if (m_cache_file != NULL)
	{
		bool t_success = true;
		
		IO_stat t_status;
		
		t_success = (IO_NORMAL == MCS_seek_set(m_cache_file, p_offset));
		if (t_success)
			t_success = (IO_ERROR != MCS_read(p_buffer, 1, p_length, m_cache_file));
		
		if (t_success)
		{
			r_read = p_length;
		}
		
		return t_success;
	}
	
	r_read = 0;
	return true;
}
Beispiel #5
0
bool MCSystemGetRotationRateReading(MCSensorRotationRateReading &r_reading, bool p_detailed)
{
    if (s_rotation_rate_reading == nil)
        return false;
    
    MCMemoryCopy(&r_reading, s_rotation_rate_reading, sizeof(MCSensorRotationRateReading));
    return true;
}
Beispiel #6
0
bool MCSystemGetAccelerationReading(MCSensorAccelerationReading &r_reading, bool p_detailed)
{
    if (s_acceleration_reading == nil)
        return false;
    
    MCMemoryCopy(&r_reading, s_acceleration_reading, sizeof(MCSensorAccelerationReading));
    return true;
}
Beispiel #7
0
bool MCSystemGetHeadingReading(MCSensorHeadingReading &r_reading, bool p_detailed)
{
    if (s_heading_reading == nil)
        return false;
    
    MCMemoryCopy(&r_reading, s_heading_reading, sizeof(MCSensorHeadingReading));
    return true;
}
Beispiel #8
0
bool deserialize_bytes(const char *p_stream, uint32_t p_stream_size, uint32_t &r_offset, void *p_dest, uint32_t p_size)
{
	if (r_offset + p_size > p_stream_size)
		return false;

	MCMemoryCopy(p_dest, p_stream + r_offset, p_size);
	r_offset += p_size;
	return true;
}
// 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);
}
Beispiel #10
0
static void gif_paste_image(MCImageBitmap *p_dst, MCImageBitmap *p_src, int32_t p_x_offset, int32_t p_y_offset)
{
	if (p_x_offset < 0 || p_y_offset < 0 ||
		p_x_offset + p_src->width > p_dst->width ||
		p_y_offset + p_src->width > p_dst->width)
		return;

	uint8_t *t_src_ptr = (uint8_t*)p_src->data;
	uint8_t *t_dst_ptr = (uint8_t*)p_dst->data + p_y_offset * p_dst->stride + p_x_offset * sizeof(uint32_t);
	uindex_t t_row_bytes = p_src->width * sizeof(uint32_t);
	for(int32_t y = 0; y < p_src->height; y++)
	{
		MCMemoryCopy(t_dst_ptr, t_src_ptr, t_row_bytes);
		t_src_ptr += p_src->stride;
		t_dst_ptr += p_dst->stride;
	}
		}
Beispiel #11
0
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;
}
Beispiel #12
0
bool MCEventQueuePostImeCompose(MCStack *p_stack, bool p_enabled, uint32_t p_offset, const uint16_t *p_chars, uint32_t p_char_count)
{
	uint16_t *t_new_chars;
	if (!MCMemoryNewArray(p_char_count, t_new_chars))
		return false;

	MCEvent *t_event;
	if (!MCEventQueuePost(kMCEventTypeImeCompose, t_event))
	{
		MCMemoryDeleteArray(t_new_chars);
		return false;
	}

	t_event -> ime . stack = p_stack;
	t_event -> ime . compose . enabled = p_enabled;
	t_event -> ime . compose . offset = p_offset;
	t_event -> ime . compose . chars = t_new_chars;
	t_event -> ime . compose . char_count = p_char_count;

	MCMemoryCopy(t_new_chars, p_chars, sizeof(uint16_t) * p_char_count);

	return true;
}
Beispiel #13
0
bool MCStreamCache::AppendToCache(void *p_buffer, uint32_t p_length, uint32_t &r_written)
{
	bool t_success = true;
	
	if (m_cache_length + p_length > m_buffer_limit)
	{
		if (m_cache_file == NULL)
		{
			t_success = MCMultiPartCreateTempFile(cgi_get_upload_temp_dir(), m_cache_file, m_cache_filename);
			if (t_success && m_cache_buffer != NULL)
				t_success = (IO_NORMAL == MCS_write(m_cache_buffer, 1, m_cache_length, m_cache_file));
			
			MCMemoryDeallocate(m_cache_buffer);
			m_cache_buffer = NULL;
		}
		
		if (t_success)
			t_success = (IO_NORMAL == MCS_write(p_buffer, 1, p_length, m_cache_file));
		
		m_cache_length += p_length;
		r_written = p_length;
	}
	else
	{
		if (m_cache_buffer == NULL)
			t_success = MCMemoryAllocate(m_buffer_limit, m_cache_buffer);
		if (t_success)
		{
			MCMemoryCopy((uint8_t*)m_cache_buffer + m_cache_length, p_buffer, p_length);
			m_cache_length += p_length;
			
			r_written = p_length;
		}
	}
		
	return t_success;
}
Beispiel #14
0
bool MCGRasterCreateCGDataProvider(const MCGRaster &p_raster, const MCGIntegerRectangle &p_src_rect, bool p_copy, bool p_invert, CGDataProviderRef &r_data_provider, uint32_t &r_stride)
{
	MCAssert(p_src_rect.origin.x >= 0 && p_src_rect.origin.y >= 0);
	MCAssert(p_src_rect.origin.x + p_src_rect.size.width <= p_raster.width);
	MCAssert(p_src_rect.origin.y + p_src_rect.size.height <= p_raster.height);
	
	bool t_success = true;
	
	int32_t t_x, t_y;
	uint32_t t_width, t_height;
	t_x = p_src_rect.origin.x;
	t_y = p_src_rect.origin.y;
	t_width = p_src_rect.size.width;
	t_height = p_src_rect.size.height;
	
	uint8_t *t_src_ptr = (uint8_t*)MCGRasterGetPixelPtr(p_raster, t_x, t_y);
	
	uint32_t t_dst_stride;
	
	if (p_invert)
		p_copy = true;
	
	CGDataProviderRef t_data_provider = nil;
	if (!p_copy)
	{
		t_dst_stride = p_raster.stride;
		t_data_provider = CGDataProviderCreateWithData(nil, t_src_ptr, t_height * p_raster.stride, __CGDataProviderDeallocate);
		t_success = t_data_provider != nil;
        if (!t_success)
            MCMemoryDeallocate(t_src_ptr);
	}
	else
	{
		uint8_t* t_buffer = nil;
		
		t_dst_stride = t_width * sizeof(uint32_t);
		uindex_t t_buffer_size = t_height * t_dst_stride;
		t_success = MCMemoryAllocate(t_buffer_size, t_buffer);
		
		if (t_success)
		{
			int32_t t_src_stride;
			
			uint8_t* t_dst_ptr = t_buffer;
			if (!p_invert)
			{
				t_src_stride = p_raster.stride;
			}
			else
			{
				t_src_ptr += ((int32_t)t_height - 1) * p_raster.stride;
				t_src_stride = -p_raster.stride;
			}
			
			for (uindex_t y = 0; y < t_height; y++)
			{
				MCMemoryCopy(t_dst_ptr, t_src_ptr, t_dst_stride);
				t_dst_ptr += t_dst_stride;
				t_src_ptr += t_src_stride;
			}
		}
		if (t_success)
		{
			t_data_provider = CGDataProviderCreateWithData(nil, t_buffer, t_buffer_size, __CGDataProviderDeallocate);
			t_success = t_data_provider != nil;
		}
		
		if (!t_success)
			MCMemoryDeallocate(t_buffer);
	}
	
	if (t_success)
	{
		r_data_provider = t_data_provider;
		r_stride = t_dst_stride;
	}
	
	return t_success;
}
Beispiel #15
0
bool MCGRasterToCGImage(const MCGRaster &p_raster, MCGRectangle p_src_rect, CGColorSpaceRef p_colorspace, bool p_copy, bool p_invert, CGImageRef &r_image)
{
	bool t_success = true;
	
	int32_t t_x, t_y;
	uint32_t t_width, t_height;
	t_x = p_src_rect.origin.x;
	t_y = p_src_rect.origin.y;
	t_width = p_src_rect.size.width;
	t_height = p_src_rect.size.height;
	
	/* OVERHAUL - REVISIT: pixel formats */
	const uint8_t *t_src_ptr = (uint8_t*)p_raster.pixels;
	t_src_ptr += t_y * p_raster.stride + t_x * sizeof(uint32_t);
	
	uint32_t t_dst_stride;
	
	if (p_invert)
		p_copy = true;
	
	CGImageRef t_image = nil;
	CGDataProviderRef t_data_provider = nil;
	
	if (!p_copy)
	{
		t_dst_stride = p_raster.stride;
		t_success = nil != (t_data_provider = CGDataProviderCreateWithData(nil, t_src_ptr, t_height * p_raster.stride, nil));
	}
	else
	{
		uint8_t* t_buffer = nil;
		
		t_dst_stride = t_width * sizeof(uint32_t);
		uindex_t t_buffer_size = t_height * t_dst_stride;
		t_success = MCMemoryAllocate(t_buffer_size, t_buffer);
		
		if (t_success)
		{
			int32_t t_src_stride;
			
			uint8_t* t_dst_ptr = t_buffer;
			if (!p_invert)
			{
				t_src_stride = p_raster.stride;
			}
			else
			{
				t_src_ptr += ((int32_t)t_height - 1) * p_raster.stride;
				t_src_stride = -p_raster.stride;
			}
			
			for (uindex_t y = 0; y < t_height; y++)
			{
				MCMemoryCopy(t_dst_ptr, t_src_ptr, t_dst_stride);
				t_dst_ptr += t_dst_stride;
				t_src_ptr += t_src_stride;
			}
		}
		if (t_success)
			t_success = nil != (t_data_provider = CGDataProviderCreateWithData(nil, t_buffer, t_buffer_size, __CGDataProviderDeallocate));
		
		if (!t_success)
			MCMemoryDeallocate(t_buffer);
		
	}
	
	// IM-2013-08-21: [[ RefactorGraphics ]] Refactor CGImage creation code to be pixel-format independent
	CGBitmapInfo t_bm_info;
	t_bm_info = MCGPixelFormatToCGBitmapInfo(kMCGPixelFormatNative, true);
	
	if (t_success)
		t_success = nil != (t_image = CGImageCreate(t_width, t_height, 8, 32, t_dst_stride, p_colorspace, t_bm_info, t_data_provider, nil, true, kCGRenderingIntentDefault));
	
	CGDataProviderRelease(t_data_provider);
	
	if (t_success)
		r_image = t_image;
	
	return t_success;
}
Beispiel #16
0
static int CALLBACK MCTextLayoutStyleItemCallback(HDC p_dc, HANDLETABLE *p_handles, const ENHMETARECORD *p_record, int p_object_count, LPARAM p_context)
{
	// This method assumes that the order of the TextOut records is in logical
	// order - i.e. no reversing for right-to-left text. This should be a valid
	// assumption to make since each SCRIPT_ITEM is rendered individually and
	// each such item is either all LTR or all RTL.
	
	// Additionally, it assumes that all printable chars (i.e. non-control) in
	// the analysed string will be part of some ExtTextOut record, even if the
	// suggested font (with linking) doesn't contain the characters.

	// Finally, it assumes that errant records which should not be rendered cause
	// a reference point advance of 0.

	MCTextLayoutStyleItemContext *context;
	context = (MCTextLayoutStyleItemContext *)p_context;

	bool t_success;
	t_success = true;

	bool t_flush;
	t_flush = false;

	int32_t t_new_pending_x;
	uint32_t t_new_pending_char_count;
	unichar_t *t_new_pending_chars;
	MCTextLayoutFont *t_new_pending_font;
	t_new_pending_x = 0;
	t_new_pending_char_count = 0;
	t_new_pending_chars = nil;
	t_new_pending_font = nil;

	switch(p_record -> iType)
	{
	case EMR_EXTCREATEFONTINDIRECTW:
		{
			EMREXTCREATEFONTINDIRECTW *t_record;
			t_record = (EMREXTCREATEFONTINDIRECTW *)p_record;

			// Attempt to create the font with the given info.
			p_handles -> objectHandle[t_record -> ihFont] = CreateFontIndirectW(&t_record -> elfw . elfLogFont);
			if (p_handles -> objectHandle[t_record -> ihFont] == nil)
				t_success = false;
		}
		break;
	case EMR_SELECTOBJECT:
		{
			EMRSELECTOBJECT *t_record;
			t_record = (EMRSELECTOBJECT *)p_record;

			// If the object being selected is a font, update our current font.
			if (GetObjectType(p_handles -> objectHandle[t_record -> ihObject]) == OBJ_FONT)
				t_success = MCTextLayoutFontFromHFONT((HFONT)p_handles -> objectHandle[t_record -> ihObject], context -> current_font);
		}
		break;
	case EMR_DELETEOBJECT:
		{
			EMRDELETEOBJECT *t_record;
			t_record = (EMRDELETEOBJECT *)p_record;

			// If the object being deleted is our current font, reset selection
			// to nil.
			if (p_handles -> objectHandle[t_record -> ihObject] == context -> current_font)
				context -> current_font = context -> primary_font;

			DeleteObject(p_handles -> objectHandle[t_record -> ihObject]);
			p_handles -> objectHandle[t_record -> ihObject] = nil;
		}
		break;
	case EMR_EXTTEXTOUTW:
		{
			EMREXTTEXTOUTW *t_record;
			t_record = (EMREXTTEXTOUTW *)p_record;

			unichar_t *t_run_chars;
			uint32_t t_run_char_count;
			t_run_chars = (unichar_t *)((char *)p_record + t_record -> emrtext . offString);
			t_run_char_count = t_record -> emrtext . nChars;

			if (t_run_char_count > 0)
			{
				if (MCMemoryNewArray(t_run_char_count, t_new_pending_chars))
				{
					t_flush = true;
					t_new_pending_x = t_record -> emrtext . ptlReference . x;
					t_new_pending_font = context -> current_font;
					t_new_pending_char_count = t_run_char_count;
					MCMemoryCopy(t_new_pending_chars, t_run_chars, t_new_pending_char_count * sizeof(uint16_t));
				}
				else
					t_success = false;
			}
		}
		break;
	case EMR_EOF:
		t_new_pending_x = MAXINT4;
		t_flush = true;
		break;
	}

	if (t_success && t_flush)
	{
		if (context -> pending_chars != nil && t_new_pending_x != context -> pending_x)
			t_success = MCTextLayoutLinkItem(*(context -> state), context -> analysis, context -> pending_chars, context -> pending_char_count, context -> pending_font);
		
		MCMemoryDeleteArray(context -> pending_chars);

		context -> pending_chars = t_new_pending_chars;
		context -> pending_char_count = t_new_pending_char_count;
		context -> pending_font = t_new_pending_font;
		context -> pending_x = t_new_pending_x;
	}

	if (!t_success)
		MCMemoryDeleteArray(context -> pending_chars);

	return t_success;
}
Beispiel #17
0
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;
}
Beispiel #18
0
void MCGCacheTableSet(MCGCacheTableRef self, void *p_key, uint32_t p_key_length, void *p_value, uint32_t p_value_length)
{
	if (self == NULL)
		return;
	
	MCAssert(sizeof(uintptr_t) >= p_value_length);
	
	if (self -> bytes_used >= self -> max_bytes)
	{
		uindex_t t_discard_bucket;
		t_discard_bucket = rand() % self -> total_buckets;
		while (self -> bytes_used >= self -> max_bytes)
		{			
			while (self -> pairs[t_discard_bucket] . key == NULL)
			{
				t_discard_bucket++;
				if (t_discard_bucket >= self -> total_buckets)
					t_discard_bucket -= self -> total_buckets;
			}
			
			MCGCacheTableDiscardPair(self, t_discard_bucket);
			
			//MCLog("MCGCacheTableSet: Max bytes reached. Hash %d discarded.", t_discard_bucket);
		}
	}
	
	if (self -> used_buckets >= self -> max_occupancy)
	{
		uindex_t t_discard_bucket;
		t_discard_bucket = rand() % self -> total_buckets;			
		while (self -> pairs[t_discard_bucket] . key == NULL)
		{
			t_discard_bucket++;
			if (t_discard_bucket >= self -> total_buckets)
				t_discard_bucket -= self -> total_buckets;
		}
		
		MCGCacheTableDiscardPair(self, t_discard_bucket);
		
		//MCLog("MCGCacheTableSet: Max occupancy reached. Hash %d discarded.", t_discard_bucket);
	}
		
	hash_t t_hash;
	t_hash = MCGHashBytes(p_key, p_key_length);
	
	uindex_t t_target_bucket;
	t_target_bucket = MCGCacheTableLookup(self, p_key, p_key_length, t_hash);
	
	if (t_target_bucket == UINDEX_MAX)
	{
		t_target_bucket = t_hash % self -> total_buckets;
		MCMemoryDelete(self -> pairs[t_target_bucket] . key);
		
		self -> bytes_used -= self -> pairs[t_target_bucket] . key_length;
		
		self -> pairs[t_target_bucket] . hash = t_hash;
		self -> pairs[t_target_bucket] . key = p_key;
		self -> pairs[t_target_bucket] . key_length = p_key_length;
		
		self -> pairs[t_target_bucket] . value = NULL;
		MCMemoryCopy(&self -> pairs[t_target_bucket] . value, p_value, p_value_length);
		
		self -> bytes_used += p_key_length;
		
		//MCLog("MCGCacheTableSet: Cache table overflow. Hash %d thrown out.", t_target_bucket);
	}
	else if (self -> pairs[t_target_bucket] . value != NULL)
	{
		MCMemoryDelete(p_key);
				
		self -> pairs[t_target_bucket] . value = NULL;
		MCMemoryCopy(&self -> pairs[t_target_bucket] . value, p_value, p_value_length);
		
		//MCLog("MCGCacheTableSet: Cache table overwrite. Hash %d rewritten.", t_target_bucket);
	}
	else
	{
		self -> pairs[t_target_bucket] . hash = t_hash;
		self -> pairs[t_target_bucket] . key = p_key;
		self -> pairs[t_target_bucket] . key_length = p_key_length;
		MCMemoryCopy(&self -> pairs[t_target_bucket] . value, p_value, p_value_length);
		
		self -> bytes_used += p_key_length;
		self -> used_buckets++;
		
		//MCLog("MCGCacheTableSet: Cache table write. Hash %d written.", t_target_bucket);
	}
}