// Returns true if this range is wholly contained within another range list.
bool UnicodeRange::IsContained(const UnicodeRangeList& rhs)
{
	for (size_t i = 0; i < rhs.size(); ++i)
	{
		if (IsContained(rhs[i]))
			return true;
	}

	return false;
}
// Builds up a list of unicode ranges from a comma-separated list of unicode ranges in string form.
bool UnicodeRange::BuildList(UnicodeRangeList& list, const String& unicode_range)
{
	StringList unicode_ranges;
	StringUtilities::ExpandString(unicode_ranges, unicode_range);

	for (size_t i = 0; i < unicode_ranges.size(); ++i)
	{
		UnicodeRange range;
		if (!range.Initialise(unicode_ranges[i]))
			return false;

		list.push_back(range);
	}

	// Collapse contiguous ranges.
	for (size_t i = 0; i < list.size(); ++i)
	{
		size_t j = i + 1;
		while (j < list.size())
		{
			if (list[i].IsContiguous(list[j]))
			{
				list[i] = list[i].Join(list[j]);
				list.erase(list.begin() + j);
			}
			else
				++j;
		}
	}

	return !list.empty();
}
Beispiel #3
0
// Returns a handle for positioning and rendering this face at the given size.
Rocket::Core::FontFaceHandle* FontFace::GetHandle(const String& _raw_charset, int size)
{
	UnicodeRangeList charset;

	HandleMap::iterator iterator = handles.find(size);
	if (iterator != handles.end())
	{
		const HandleList& handles = (*iterator).second;

		// Check all the handles if their charsets match the requested one exactly (ie, were specified by the same
		// string).
		String raw_charset(_raw_charset);
		for (size_t i = 0; i < handles.size(); ++i)
		{
			if (handles[i]->GetRawCharset() == _raw_charset)
			{
				handles[i]->AddReference();
				return (Rocket::Core::FreeType::FontFaceHandle*)handles[i];
			}
		}

		// Check all the handles if their charsets contain the requested charset.
		if (!UnicodeRange::BuildList(charset, raw_charset))
		{
			Log::Message(Log::LT_ERROR, "Invalid font charset '%s'.", _raw_charset.CString());
			return NULL;
		}

		for (size_t i = 0; i < handles.size(); ++i)
		{
			bool range_contained = true;

			const UnicodeRangeList& handle_charset = handles[i]->GetCharset();
			for (size_t j = 0; j < charset.size() && range_contained; ++j)
			{
				if (!charset[j].IsContained(handle_charset))
					range_contained = false;
			}

			if (range_contained)
			{
				handles[i]->AddReference();
				return (Rocket::Core::FreeType::FontFaceHandle*)handles[i];
			}
		}
	}

	// See if this face has been released.
	if (face == NULL)
	{
		Log::Message(Log::LT_WARNING, "Font face has been released, unable to generate new handle.");
		return NULL;
	}

	// Construct and initialise the new handle.
	FontFaceHandle* handle = new FontFaceHandle();
	if (!handle->Initialise(face, _raw_charset, size))
	{
		handle->RemoveReference();
		return NULL;
	}

	// Save the handle, and add a reference for the callee. The initial reference will be removed when the font face
	// releases it.
	if (iterator != handles.end())
		(*iterator).second.push_back(handle);
	else
		handles[size] = HandleList(1, handle);

	handle->AddReference();

	return handle;
}