Exemple #1
0
void text_renderer::prepare_glyphs(glyph_positions const& positions)
{
    FT_Matrix matrix;
    FT_Vector pen;
    FT_Error  error;

    glyphs_.clear();
    glyphs_.reserve(positions.size());

    for (auto const& glyph_pos : positions)
    {
        glyph_info const& glyph = glyph_pos.glyph;
        FT_Int32 load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;

        FT_Face face = glyph.face->get_face();
        if (glyph.face->is_color())
        {
            load_flags |= FT_LOAD_COLOR ;
            if (face->num_fixed_sizes > 0)
            {
                int scaled_size = static_cast<int>(glyph.format->text_size * scale_factor_);
                int best_match = 0;
                int diff = std::abs(scaled_size - face->available_sizes[0].width);
                for (int i = 1; i < face->num_fixed_sizes; ++i)
                {
                    int ndiff = std::abs(scaled_size - face->available_sizes[i].height);
                    if (ndiff < diff)
                    {
                        best_match = i;
                        diff = ndiff;
                    }
                }
                error = FT_Select_Size(face, best_match);
            }
        }
        else
        {
            glyph.face->set_character_sizes(glyph.format->text_size * scale_factor_);
        }

        double size = glyph.format->text_size * scale_factor_;
        matrix.xx = static_cast<FT_Fixed>( glyph_pos.rot.cos * 0x10000L);
        matrix.xy = static_cast<FT_Fixed>(-glyph_pos.rot.sin * 0x10000L);
        matrix.yx = static_cast<FT_Fixed>( glyph_pos.rot.sin * 0x10000L);
        matrix.yy = static_cast<FT_Fixed>( glyph_pos.rot.cos * 0x10000L);

        pixel_position pos = glyph_pos.pos + glyph.offset.rotate(glyph_pos.rot);
        pen.x = static_cast<FT_Pos>(pos.x * 64);
        pen.y = static_cast<FT_Pos>(pos.y * 64);

        FT_Set_Transform(face, &matrix, &pen);
        error = FT_Load_Glyph(face, glyph.glyph_index, load_flags);
        if (error) continue;
        FT_Glyph image;
        error = FT_Get_Glyph(face->glyph, &image);
        if (error) continue;
        box2d<double> bbox(0, glyph_pos.glyph.ymin(), glyph_pos.glyph.advance(), glyph_pos.glyph.ymax());
        glyphs_.emplace_back(image, *glyph.format, pos, glyph_pos.rot, size, bbox);
    }
}
JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_graphics_g2d_freetype_FreeType_selectSize(JNIEnv* env, jclass clazz, jlong face, jint strike_index) {


//@line:608

		return !FT_Select_Size((FT_Face)face, strike_index);
	

}
Exemple #3
0
  T42_Size_Select( T42_Size  size,
                   FT_ULong  strike_index )
  {
    T42_Face  face = (T42_Face)size->root.face;
    FT_Error  error;


    FT_Activate_Size( size->ttsize );

    error = FT_Select_Size( face->ttf_face, (FT_Int)strike_index );
    if ( !error )
      ( (FT_Size)size )->metrics = face->ttf_face->size->metrics;

    return error;

  }
Exemple #4
0
  T42_Size_Select( FT_Size   t42size,         /* T42_Size */
                   FT_ULong  strike_index )
  {
    T42_Size  size = (T42_Size)t42size;
    T42_Face  face = (T42_Face)t42size->face;
    FT_Error  error;


    FT_Activate_Size( size->ttsize );

    error = FT_Select_Size( face->ttf_face, (FT_Int)strike_index );
    if ( !error )
      t42size->metrics = face->ttf_face->size->metrics;

    return error;

  }
FT_Error freetype_font::set_ideal_character_size(int iWidth, int iHeight)
{
    if(font_face == nullptr)
        return FT_Err_Invalid_Face_Handle;

    if(is_monochrome() || iHeight <= 14 || iWidth <= 9)
    {
        // Look for a bitmap strike of a similar size
        int iBestBitmapScore = 50;
        FT_Int iBestBitmapIndex = -1;
        for(FT_Int i = 0; i < font_face->num_fixed_sizes; ++i)
        {
            if(font_face->available_sizes[i].height > iHeight)
                continue;
            int iDeltaH = iHeight - font_face->available_sizes[i].height;
            int iDeltaW = font_face->available_sizes[i].width - iWidth;
            int iScore = iDeltaH * iDeltaH * 3 + iDeltaW * iDeltaW;
            if(iScore < iBestBitmapScore)
            {
                iBestBitmapScore = iScore;
                iBestBitmapIndex = i;
            }
        }

        // Select the bitmap strike, if there was one
        if(iBestBitmapIndex != -1)
            return FT_Select_Size(font_face, iBestBitmapIndex);
    }

    // Go with the original size request if there was no bitmap strike, unless
    // the size was very small, in which case scale things up, as vector fonts
    // look rather poor at small sizes.
    if(iHeight < 14)
    {
        iWidth = iWidth * 14 / iHeight;
        iHeight = 14;
    }
    if(iWidth < 9)
    {
        iHeight = iHeight * 9 / iWidth;
        iWidth = 9;
    }
    return FT_Set_Pixel_Sizes(font_face, iWidth, iHeight);
}
Exemple #6
0
/**
 * Create a new FreeTypeFontCache.
 * @param fs     The font size that is going to be cached.
 * @param face   The font that has to be loaded.
 * @param pixels The number of pixels this font should be high.
 */
FreeTypeFontCache::FreeTypeFontCache(FontSize fs, FT_Face face, int pixels) : FontCache(fs), face(face), glyph_to_sprite(NULL)
{
	assert(face != NULL);

	if (pixels == 0) {
		/* Try to determine a good height based on the minimal height recommended by the font. */
		pixels = _default_font_height[this->fs];

		TT_Header *head = (TT_Header *)FT_Get_Sfnt_Table(this->face, ft_sfnt_head);
		if (head != NULL) {
			/* Font height is minimum height plus the difference between the default
			 * height for this font size and the small size. */
			int diff = _default_font_height[this->fs] - _default_font_height[FS_SMALL];
			pixels = Clamp(min(head->Lowest_Rec_PPEM, 20) + diff, _default_font_height[this->fs], MAX_FONT_SIZE);
		}
	}

	FT_Error err = FT_Set_Pixel_Sizes(this->face, 0, pixels);
	if (err != FT_Err_Ok) {

		/* Find nearest size to that requested */
		FT_Bitmap_Size *bs = this->face->available_sizes;
		int i = this->face->num_fixed_sizes;
		if (i > 0) { // In pathetic cases one might get no fixed sizes at all.
			int n = bs->height;
			FT_Int chosen = 0;
			for (; --i; bs++) {
				if (abs(pixels - bs->height) >= abs(pixels - n)) continue;
				n = bs->height;
				chosen = this->face->num_fixed_sizes - i;
			}

			/* Don't use FT_Set_Pixel_Sizes here - it might give us another
			 * error, even though the size is available (FS#5885). */
			err = FT_Select_Size(this->face, chosen);
		}
	}

	if (err == FT_Err_Ok) {
		this->units_per_em = this->face->units_per_EM;
		this->ascender     = this->face->size->metrics.ascender >> 6;
		this->descender    = this->face->size->metrics.descender >> 6;
		this->height       = this->ascender - this->descender;
	} else {
int EMSCRIPTEN_KEEPALIVE c_Face_selectSize(long face, int strike_index) {
    return !FT_Select_Size((FT_Face)face, strike_index);
}
	FT_Face ResourceTrueTypeFont::loadFace(const FT_Library& _ftLibrary, uint8*& _fontBuffer)
	{
		FT_Face result = nullptr;

		// Load the font file.
		IDataStream* datastream = DataManager::getInstance().getData(mSource);

		if (datastream == nullptr)
			return result;

		size_t fontBufferSize = datastream->size();
		_fontBuffer = new uint8[fontBufferSize];
		datastream->read(_fontBuffer, fontBufferSize);

		DataManager::getInstance().freeData(datastream);
		datastream = nullptr;

		// Determine how many faces the font contains.
		if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, -1, &result) != 0)
			MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!");

		FT_Long numFaces = result->num_faces;
		FT_Long faceIndex = 0;

		// Load the first face.
		if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, faceIndex, &result) != 0)
			MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!");

		if (result->face_flags & FT_FACE_FLAG_SCALABLE)
		{
			// The font is scalable, so set the font size by first converting the requested size to FreeType's 26.6 fixed-point
			// format.
			FT_F26Dot6 ftSize = (FT_F26Dot6)(mSize * (1 << 6));

			if (FT_Set_Char_Size(result, ftSize, 0, mResolution, mResolution) != 0)
				MYGUI_EXCEPT("ResourceTrueTypeFont: Could not set the font size for '" << getResourceName() << "'!");

			// If no code points have been specified, use the Unicode Basic Multilingual Plane by default.
			if (mCharMap.empty())
				addCodePointRange(0, 0xFFFF);
		}
		else
		{
			// The font isn't scalable, so try to load it as a Windows FNT/FON file.
			FT_WinFNT_HeaderRec fnt;

			// Enumerate all of the faces in the font and select the smallest one that's at least as large as the requested size
			// (after adjusting for resolution). If none of the faces are large enough, use the largest one.
			std::map<float, FT_Long> faceSizes;

			do
			{
				if (FT_Get_WinFNT_Header(result, &fnt) != 0)
					MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!");

				faceSizes.insert(std::make_pair((float)fnt.nominal_point_size * fnt.vertical_resolution / mResolution, faceIndex));

				FT_Done_Face(result);

				if (++faceIndex < numFaces)
					if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, faceIndex, &result) != 0)
						MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!");
			}
			while (faceIndex < numFaces);

			std::map<float, FT_Long>::const_iterator iter = faceSizes.lower_bound(mSize);

			faceIndex = (iter != faceSizes.end()) ? iter->second : faceSizes.rbegin()->second;

			if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, faceIndex, &result) != 0)
				MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!");

			// Select the first bitmap strike available in the selected face. This needs to be done explicitly even though Windows
			// FNT/FON files contain only one bitmap strike per face.
			if (FT_Select_Size(result, 0) != 0)
				MYGUI_EXCEPT("ResourceTrueTypeFont: Could not set the font size for '" << getResourceName() << "'!");

			// Windows FNT/FON files do not support Unicode, so restrict the code-point range to either ISO-8859-1 or ASCII,
			// depending on the font's encoding.
			if (mCharMap.empty())
			{
				// No code points have been specified, so add the printable ASCII range by default.
				addCodePointRange(0x20, 0x7E);

				// Additionally, if the font's character set is CP-1252, add the range of non-ASCII 8-bit code points that are
				// common between CP-1252 and ISO-8859-1; i.e., everything but 0x80 through 0x9F.
				if (fnt.charset == FT_WinFNT_ID_CP1252)
					addCodePointRange(0xA0, 0xFF);
			}
			else
			{
				// Some code points have been specified, so remove anything in the non-printable ASCII range as well as anything
				// over 8 bits.
				removeCodePointRange(0, 0x1F);
				removeCodePointRange(0x100, std::numeric_limits<Char>::max());

				// Additionally, remove non-ASCII 8-bit code points (plus ASCII DEL, 0x7F). If the font's character set is CP-1252,
				// remove only the code points that differ between CP-1252 and ISO-8859-1; otherwise, remove all of them.
				if (fnt.charset == FT_WinFNT_ID_CP1252)
					removeCodePointRange(0x7F, 0x9F);
				else
					removeCodePointRange(0x7F, 0xFF);
			}
		}

		return result;
	}