Example #1
0
	Font_Cache FontFamily_Impl::get_font(const FontDescription &desc, float pixel_ratio)
	{
		// Find cached version
		for (auto &cache : font_cache)
		{
			if (cache.pixel_ratio != pixel_ratio)
				continue;
			if (desc.get_style() != cache.engine->get_desc().get_style())
				continue;
			if (desc.get_weight() != cache.engine->get_desc().get_weight())
				continue;
			if (desc.get_subpixel() != cache.engine->get_desc().get_subpixel())
				continue;
			if (desc.get_anti_alias() != cache.engine->get_desc().get_anti_alias())
				continue;

			if (cache.engine->is_automatic_recreation_allowed())
			{
				if (desc.get_height() != cache.engine->get_desc().get_height())
					continue;
			}

			return cache;
		}
		return Font_Cache();
	}
Example #2
0
	std::string FontConfig::match_font(const std::string &typeface_name, const FontDescription &desc) const
	{
		FcPattern * fc_pattern = nullptr;
		FcPattern * fc_match = nullptr;
		try
		{
			int weight = static_cast<int>(desc.get_weight());

			// Build font matching pattern.
			fc_pattern = FcPatternBuild(nullptr,
				FC_FAMILY, FcTypeString, typeface_name.c_str(),
				FC_PIXEL_SIZE, FcTypeDouble, (double)std::abs(desc.get_height()),
				FC_WEIGHT, FcTypeInteger, (weight > 0) ? (int)(weight * (FC_WEIGHT_HEAVY / 900.0)) : FC_WEIGHT_NORMAL,
				FC_SLANT, FcTypeInteger, (desc.get_style() == clan::FontStyle::italic) ? FC_SLANT_ITALIC : ((desc.get_style() == clan::FontStyle::oblique) ? FC_SLANT_OBLIQUE : FC_SLANT_ROMAN),
				FC_SPACING, FcTypeInteger, FC_PROPORTIONAL,
				(char*) nullptr
				);
			if (!fc_pattern)
			{
				throw Exception("CL_FontConfig: Building FontConfig pattern failed.");
			}

			// Execute any needed param substitutions required by the system config.
			if (FcTrue != FcConfigSubstitute(fc_config, fc_pattern, FcMatchPattern))
			{
				throw Exception("CL_FontConfig: Font config substitutions failed.");
			}

			// Supply default values for underspecified font patterns. Never fails.
			FcDefaultSubstitute(fc_pattern);

			// Find best match for pattern and extract filename.
			FcResult match_result; // Doesn't appear to be actually updated.
			fc_match = FcFontMatch(fc_config, fc_pattern, &match_result);
			FcChar8 * fc_font_file_path = nullptr;
			if (FcResultMatch != FcPatternGetString(fc_match, FC_FILE, 0, &fc_font_file_path))
			{
				throw Exception("CL_FontConfig: Could not resolve font pattern to a font file.");
			}

			// Release resources and return results.
			std::string cl_font_file_path((char*)fc_font_file_path);
			FcPatternDestroy(fc_match);
			FcPatternDestroy(fc_pattern);
			return cl_font_file_path;
		}
		catch (...)
		{
			// If any exceptions thrown, ensure fontconfig resources are released.
			if (fc_match) FcPatternDestroy(fc_match);
			if (fc_pattern) FcPatternDestroy(fc_pattern);
			throw;
		}
	}
Example #3
0
	Font_Cache FontFamily_Impl::copy_font(const FontDescription &desc, float pixel_ratio)
	{
		// Find existing typeface, to obtain shared data that we can copy
		FontFamily_Definition font_definition;
		bool found = false;

		// Find find an exact match using style and weight
		for (auto &definitions : font_definitions)
		{
			if (desc.get_style() != definitions.desc.get_style())
				continue;
			if (desc.get_weight() != definitions.desc.get_weight())
				continue;

			font_definition = definitions;
			found = true;
			break;
		}

		// Else find the first font
		if (!found)
		{
			if (!font_definitions.empty())
			{
				font_definition = font_definitions[0];
				found = true;
			}
		}

		if (!found)
		{
			// Could not find a cached version of the font to use as reference
			font_face_load(desc, family_name, pixel_ratio);
		}
		else
		{
			if (!font_definition.font_databuffer.is_null())
			{
				// Cached font is allocated via a font databuffer
				font_face_load(desc, font_definition.font_databuffer, pixel_ratio);
			}
			else
			{
				// Cached font has allocated the typeface_name
				font_face_load(desc, font_definition.typeface_name, pixel_ratio);
			}
		}

		return font_cache.back();
	}