Beispiel #1
0
  ftc_size_node_flush( FTC_SizeNode   node,
                       FTC_SizeQuery  query )
  {
    FT_Size   size = node->size;
    FT_Error  error;


    if ( size->face == query->face )
    {
      FT_Activate_Size( size );
      error = FT_Set_Pixel_Sizes( query->face, query->width, query->height );
      if ( error )
      {
        FT_Done_Size( size );
        node->size = NULL;
      }
    }
    else
    {
      FT_Done_Size( size );
      node->size = NULL;

      error = ftc_size_node_init( node, query );
    }
    return error;
  }
Beispiel #2
0
  ftc_face_node_init( FTC_MruNode  ftcnode,
                      FT_Pointer   ftcface_id,
                      FT_Pointer   ftcmanager )
  {
    FTC_FaceNode  node    = (FTC_FaceNode)ftcnode;
    FTC_FaceID    face_id = (FTC_FaceID)ftcface_id;
    FTC_Manager   manager = (FTC_Manager)ftcmanager;
    FT_Error      error;


    node->face_id = face_id;

    error = manager->request_face( face_id,
                                   manager->library,
                                   manager->request_data,
                                   &node->face );
    if ( !error )
    {
      /* destroy initial size object; it will be re-created later */
      if ( node->face->size )
        FT_Done_Size( node->face->size );
    }

    return error;
  }
Beispiel #3
0
  static FT_Error
  ftc_scaler_lookup_size( FTC_Manager  manager,
                          FTC_Scaler   scaler,
                          FT_Size     *asize )
  {
    FT_Face   face;
    FT_Size   size = NULL;
    FT_Error  error;


    error = FTC_Manager_LookupFace( manager, scaler->face_id, &face );
    if ( error )
      goto Exit;

    error = FT_New_Size( face, &size );
    if ( error )
      goto Exit;

    FT_Activate_Size( size );

    if ( scaler->pixel )
      error = FT_Set_Pixel_Sizes( face, scaler->width, scaler->height );
    else
      error = FT_Set_Char_Size( face, scaler->width, scaler->height,
                                scaler->x_res, scaler->y_res );
    if ( error )
    {
      FT_Done_Size( size );
      size = NULL;
    }

  Exit:
    *asize = size;
    return error;
  }
Beispiel #4
0
 ftc_size_node_done( FTC_SizeNode  node )
 {
   if ( node->size )
   {
     FT_Done_Size( node->size );
     node->size = NULL;
   }
 }
Beispiel #5
0
Font::~Font() {
	
	if(m_size) {
		FT_Done_Size(m_size);
	}
	
	delete m_textures;
	
}
Beispiel #6
0
  ftc_size_node_done( FTC_MruNode  ftcnode,
                      FT_Pointer   data )
  {
    FTC_SizeNode  node = (FTC_SizeNode)ftcnode;
    FT_Size       size = node->size;
    FT_UNUSED( data );


    if ( size )
      FT_Done_Size( size );
  }
Beispiel #7
0
/*
 * Class:     sage_FreetypeFont
 * Method:    closeFontFace0
 * Signature: (J)Z
 */
JNIEXPORT jboolean JNICALL Java_sage_FreetypeFont_closeFontFace0
  (JNIEnv *env, jobject jo, jlong fontPtr)
{
	FTDataStruct* fontData = (FTDataStruct*)(intptr_t) fontPtr;
	// NOTE: WE CAN ONLY CLOSE THE SIZE SINCE OTHERS MIGHT STILL BE USING THE FACE!!!!
	// THIS LEAKS MEMORY IF YOU THINK IT'LL CLOSE THE FONT FACE!!!!!
	// THIS LEAKS MEMORY IF YOU THINK IT'LL CLOSE THE FONT FACE!!!!!
	//FT_Face face = (FT_Face) facePtr;
	jboolean rv = FT_Done_Size(fontData->sizePtr) == 0;//FT_Done_Face(face) == 0;
	free(fontData);
	return rv;
}
Beispiel #8
0
xd::font::~font()
{
	// free all textures
	for (auto i = m_glyph_map.begin(); i != m_glyph_map.end(); ++i) {
		glDeleteTextures(1, &i->second->texture_id);
	}
	// free font sizes
	for (auto i = m_face->sizes.begin(); i != m_face->sizes.end(); ++i) {
		FT_Done_Size(i->second);
	}
	// free the font handle
	FT_Done_Face(m_face->handle);
}
Beispiel #9
0
  T42_Size_Done( T42_Size  size )
  {
    FT_Face      face    = size->root.face;
    T42_Face     t42face = (T42_Face)face;
    FT_ListNode  node;


    node = FT_List_Find( &t42face->ttf_face->sizes_list, size->ttsize );
    if ( node )
    {
      FT_Done_Size( size->ttsize );
      size->ttsize = NULL;
    }
  }
Beispiel #10
0
SkScalerContext_FreeType::~SkScalerContext_FreeType() {
    if (fFTSize != NULL) {
        FT_Done_Size(fFTSize);
    }

    SkAutoMutexAcquire  ac(gFTMutex);

    if (fFace != NULL) {
        unref_ft_face(fFace);
    }
    if (--gFTCount == 0) {
//        SkDEBUGF(("FT_Done_FreeType\n"));
        FT_Done_FreeType(gFTLibrary);
        SkDEBUGCODE(gFTLibrary = NULL;)
    }
Beispiel #11
0
  ftc_size_node_reset( FTC_MruNode  ftcnode,
                       FT_Pointer   ftcscaler,
                       FT_Pointer   ftcmanager )
  {
    FTC_SizeNode  node    = (FTC_SizeNode)ftcnode;
    FTC_Scaler    scaler  = (FTC_Scaler)ftcscaler;
    FTC_Manager   manager = (FTC_Manager)ftcmanager;


    FT_Done_Size( node->size );

    node->scaler = scaler[0];

    return ftc_scaler_lookup_size( manager, scaler, &node->size );
  }
Beispiel #12
0
  T42_Size_Done( FT_Size  t42size )             /* T42_Size */
  {
    T42_Size     size    = (T42_Size)t42size;
    FT_Face      face    = t42size->face;
    T42_Face     t42face = (T42_Face)face;
    FT_ListNode  node;


    node = FT_List_Find( &t42face->ttf_face->sizes_list, size->ttsize );
    if ( node )
    {
      FT_Done_Size( size->ttsize );
      size->ttsize = NULL;
    }
  }
Beispiel #13
0
  ftc_size_node_init( FTC_SizeNode   node,
                      FTC_SizeQuery  query )
  {
    FT_Face   face = query->face;
    FT_Size   size;
    FT_Error  error;


    node->size = NULL;
    error = FT_New_Size( face, &size );
    if ( !error )
    {
      FT_Activate_Size( size );
      error = FT_Set_Pixel_Sizes( query->face,
                                  query->width,
                                  query->height );
      if ( error )
        FT_Done_Size( size );
      else
        node->size = size;
    }
    return error;
  }
Beispiel #14
0
  T42_Face_Init( FT_Stream      stream,
                 T42_Face       face,
                 FT_Int         face_index,
                 FT_Int         num_params,
                 FT_Parameter*  params)
  {
    FT_Error          error;
    PSNames_Service   psnames;
    PSAux_Service     psaux;
    FT_Face           root    = (FT_Face)&face->root;

    FT_UNUSED( num_params );
    FT_UNUSED( params );
    FT_UNUSED( face_index );
    FT_UNUSED( stream );


    face->ttf_face       = NULL;
    face->root.num_faces = 1;

    face->psnames = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),
                                             "psnames" );
    psnames = (PSNames_Service)face->psnames;

    face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),
                                           "psaux" );
    psaux = (PSAux_Service)face->psaux;

    /* open the tokenizer, this will also check the font format */
    error = T42_Open_Face( face );
    if ( error )
      goto Exit;

    /* if we just wanted to check the format, leave successfully now */
    if ( face_index < 0 )
      goto Exit;

    /* check the face index */
    if ( face_index != 0 )
    {
      FT_ERROR(( "T42_Face_Init: invalid face index\n" ));
      error = T42_Err_Invalid_Argument;
      goto Exit;
    }

    /* Now, load the font program into the face object */

    /* Init the face object fields */
    /* Now set up root face fields */

    root->num_glyphs   = face->type1.num_glyphs;
    root->num_charmaps = 0;
    root->face_index   = face_index;

    root->face_flags  = FT_FACE_FLAG_SCALABLE;
    root->face_flags |= FT_FACE_FLAG_HORIZONTAL;
    root->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;

    if ( face->type1.font_info.is_fixed_pitch )
      root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;

    /* XXX: TODO -- add kerning with .afm support */

    /* get style name -- be careful, some broken fonts only */
    /* have a `/FontName' dictionary entry!                 */
    root->family_name = face->type1.font_info.family_name;
    if ( root->family_name )
    {
      char*  full   = face->type1.font_info.full_name;
      char*  family = root->family_name;


      if ( full )
      {
        while ( *family && *full == *family )
        {
          family++;
          full++;
        }

        root->style_name = ( *full == ' ' ? full + 1
                                          : (char *)"Regular" );
      }
      else
        root->style_name = (char *)"Regular";
    }
    else
    {
      /* do we have a `/FontName'? */
      if ( face->type1.font_name )
      {
        root->family_name = face->type1.font_name;
        root->style_name  = (char *)"Regular";
      }
    }

    /* no embedded bitmap support */
    root->num_fixed_sizes = 0;
    root->available_sizes = 0;

    /* Load the TTF font embedded in the T42 font */
    error = FT_New_Memory_Face( FT_FACE_LIBRARY( face ),
                                face->ttf_data,
                                face->ttf_size,
                                0,
                                &face->ttf_face );
    if ( error )
      goto Exit;

    FT_Done_Size( face->ttf_face->size );

    /* Ignore info in FontInfo dictionary and use the info from the  */
    /* loaded TTF font.  The PostScript interpreter also ignores it. */
    root->bbox         = face->ttf_face->bbox;
    root->units_per_EM = face->ttf_face->units_per_EM;

    root->ascender  = face->ttf_face->ascender;
    root->descender = face->ttf_face->descender;
    root->height    = face->ttf_face->height;

    root->max_advance_width  = face->ttf_face->max_advance_width;
    root->max_advance_height = face->ttf_face->max_advance_height;

    root->underline_position  = face->type1.font_info.underline_position;
    root->underline_thickness = face->type1.font_info.underline_thickness;

    root->internal->max_points   = 0;
    root->internal->max_contours = 0;

    /* compute style flags */
    root->style_flags = 0;
    if ( face->type1.font_info.italic_angle )
      root->style_flags |= FT_STYLE_FLAG_ITALIC;

    if ( face->ttf_face->style_flags & FT_STYLE_FLAG_BOLD )
      root->style_flags |= FT_STYLE_FLAG_BOLD;

    if ( face->ttf_face->face_flags & FT_FACE_FLAG_VERTICAL )
      root->face_flags |= FT_FACE_FLAG_VERTICAL;

#ifdef FT_CONFIG_OPTION_USE_CMAPS

    {
      if ( psnames && psaux )
      {
        FT_CharMapRec    charmap;
        T1_CMap_Classes  cmap_classes = psaux->t1_cmap_classes;
        FT_CMap_Class    clazz;


        charmap.face = root;

        /* first of all, try to synthetize a Unicode charmap */
        charmap.platform_id = 3;
        charmap.encoding_id = 1;
        charmap.encoding    = ft_encoding_unicode;

        FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL );

        /* now, generate an Adobe Standard encoding when appropriate */
        charmap.platform_id = 7;
        clazz               = NULL;

        switch ( face->type1.encoding_type )
        {
        case T1_ENCODING_TYPE_STANDARD:
          charmap.encoding    = ft_encoding_adobe_standard;
          charmap.encoding_id = 0;
          clazz               = cmap_classes->standard;
          break;

        case T1_ENCODING_TYPE_EXPERT:
          charmap.encoding    = ft_encoding_adobe_expert;
          charmap.encoding_id = 1;
          clazz               = cmap_classes->expert;
          break;

        case T1_ENCODING_TYPE_ARRAY:
          charmap.encoding    = ft_encoding_adobe_custom;
          charmap.encoding_id = 2;
          clazz               = cmap_classes->custom;
          break;

        case T1_ENCODING_TYPE_ISOLATIN1:
          charmap.encoding    = ft_encoding_latin_1;
          charmap.encoding_id = 3;
          clazz               = cmap_classes->unicode;
          break;

        default:
          ;
        }

        if ( clazz )
          FT_CMap_New( clazz, NULL, &charmap, NULL );

        /* Select default charmap */
        if (root->num_charmaps)
          root->charmap = root->charmaps[0];
      }
    }

#else /* !FT_CONFIG_OPTION_USE_CMAPS */

    /* charmap support -- synthetize unicode charmap if possible */
    {
      FT_CharMap  charmap = face->charmaprecs;

      
      /* synthesize a Unicode charmap if there is support in the `PSNames' */
      /* module                                                            */
      if ( psnames && psnames->unicode_value )
      {
        error = psnames->build_unicodes( root->memory,
                                         face->type1.num_glyphs,
                                         (const char**)face->type1.glyph_names,
                                         &face->unicode_map );
        if ( !error )
        {
          root->charmap        = charmap;
          charmap->face        = (FT_Face)face;
          charmap->encoding    = ft_encoding_unicode;
          charmap->platform_id = 3;
          charmap->encoding_id = 1;
          charmap++;
        }
        
        /* XXX: Is the following code correct?  It is used in t1objs.c */
        
        /* simply clear the error in case of failure (which really) */
        /* means that out of memory or no unicode glyph names       */
        error = T42_Err_Ok;
      }
      
      /* now, support either the standard, expert, or custom encoding */
      charmap->face        = (FT_Face)face;
      charmap->platform_id = 7;  /* a new platform id for Adobe fonts? */
      
      switch ( face->type1.encoding_type )
      {
      case T1_ENCODING_TYPE_STANDARD:
        charmap->encoding    = ft_encoding_adobe_standard;
        charmap->encoding_id = 0;
        break;
        
      case T1_ENCODING_TYPE_EXPERT:
        charmap->encoding    = ft_encoding_adobe_expert;
        charmap->encoding_id = 1;
        break;
        
      case T1_ENCODING_TYPE_ARRAY:
        charmap->encoding    = ft_encoding_adobe_custom;
        charmap->encoding_id = 2;
        break;
        
      case T1_ENCODING_TYPE_ISOLATIN1:
        charmap->encoding    = ft_encoding_latin_1;
        charmap->encoding_id = 3;
        break;
        
      default:
        FT_ERROR(( "T42_Face_Init: invalid encoding\n" ));
        error = T42_Err_Invalid_File_Format;
        goto Exit;
      }
      
      root->charmaps     = face->charmaps;
      root->num_charmaps = charmap - face->charmaprecs + 1;
      face->charmaps[0]  = &face->charmaprecs[0];
      face->charmaps[1]  = &face->charmaprecs[1];
    }

#endif /* !FT_CONFIG_OPTION_USE_CMAPS */

  Exit:
    return error;
  }
Beispiel #15
0
  T42_Face_Init( FT_Stream      stream,
                 T42_Face       face,
                 FT_Int         face_index,
                 FT_Int         num_params,
                 FT_Parameter*  params )
  {
    FT_Error            error;
    FT_Service_PsCMaps  psnames;
    PSAux_Service       psaux;
    FT_Face             root  = (FT_Face)&face->root;
    T1_Font             type1 = &face->type1;
    PS_FontInfo         info  = &type1->font_info;

    FT_UNUSED( num_params );
    FT_UNUSED( params );
    FT_UNUSED( face_index );
    FT_UNUSED( stream );


    face->ttf_face       = NULL;
    face->root.num_faces = 1;

    FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
    face->psnames = psnames;

    face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),
                                           "psaux" );
    psaux = (PSAux_Service)face->psaux;

    /* open the tokenizer, this will also check the font format */
    error = T42_Open_Face( face );
    if ( error )
      goto Exit;

    /* if we just wanted to check the format, leave successfully now */
    if ( face_index < 0 )
      goto Exit;

    /* check the face index */
    if ( face_index > 0 )
    {
      FT_ERROR(( "T42_Face_Init: invalid face index\n" ));
      error = T42_Err_Invalid_Argument;
      goto Exit;
    }

    /* Now load the font program into the face object */

    /* Init the face object fields */
    /* Now set up root face fields */

    root->num_glyphs   = type1->num_glyphs;
    root->num_charmaps = 0;
    root->face_index   = 0;

    root->face_flags = FT_FACE_FLAG_SCALABLE    |
                       FT_FACE_FLAG_HORIZONTAL  |
                       FT_FACE_FLAG_GLYPH_NAMES;

    if ( info->is_fixed_pitch )
      root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;

    /* We only set this flag if we have the patented bytecode interpreter. */
    /* There are no known `tricky' Type42 fonts that could be loaded with  */
    /* the unpatented interpreter.                                         */
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
    root->face_flags |= FT_FACE_FLAG_HINTER;
#endif

    /* XXX: TODO -- add kerning with .afm support */

    /* get style name -- be careful, some broken fonts only */
    /* have a `/FontName' dictionary entry!                 */
    root->family_name = info->family_name;
    /* assume "Regular" style if we don't know better */
    root->style_name = (char *)"Regular";
    if ( root->family_name )
    {
      char*  full   = info->full_name;
      char*  family = root->family_name;


      if ( full )
      {
        while ( *full )
        {
          if ( *full == *family )
          {
            family++;
            full++;
          }
          else
          {
            if ( *full == ' ' || *full == '-' )
              full++;
            else if ( *family == ' ' || *family == '-' )
              family++;
            else
            {
              if ( !*family )
                root->style_name = full;
              break;
            }
          }
        }
      }
    }
    else
    {
      /* do we have a `/FontName'? */
      if ( type1->font_name )
        root->family_name = type1->font_name;
    }

    /* no embedded bitmap support */
    root->num_fixed_sizes = 0;
    root->available_sizes = 0;

    /* Load the TTF font embedded in the T42 font */
    {
      FT_Open_Args  args;


      args.flags       = FT_OPEN_MEMORY;
      args.memory_base = face->ttf_data;
      args.memory_size = face->ttf_size;

      if ( num_params )
      {
        args.flags     |= FT_OPEN_PARAMS;
        args.num_params = num_params;
        args.params     = params;
      }

      error = FT_Open_Face( FT_FACE_LIBRARY( face ),
                            &args, 0, &face->ttf_face );
    }

    if ( error )
      goto Exit;

    FT_Done_Size( face->ttf_face->size );

    /* Ignore info in FontInfo dictionary and use the info from the  */
    /* loaded TTF font.  The PostScript interpreter also ignores it. */
    root->bbox         = face->ttf_face->bbox;
    root->units_per_EM = face->ttf_face->units_per_EM;

    root->ascender  = face->ttf_face->ascender;
    root->descender = face->ttf_face->descender;
    root->height    = face->ttf_face->height;

    root->max_advance_width  = face->ttf_face->max_advance_width;
    root->max_advance_height = face->ttf_face->max_advance_height;

    root->underline_position  = (FT_Short)info->underline_position;
    root->underline_thickness = (FT_Short)info->underline_thickness;

    /* compute style flags */
    root->style_flags = 0;
    if ( info->italic_angle )
      root->style_flags |= FT_STYLE_FLAG_ITALIC;

    if ( face->ttf_face->style_flags & FT_STYLE_FLAG_BOLD )
      root->style_flags |= FT_STYLE_FLAG_BOLD;

    if ( face->ttf_face->face_flags & FT_FACE_FLAG_VERTICAL )
      root->face_flags |= FT_FACE_FLAG_VERTICAL;

    {
      if ( psnames && psaux )
      {
        FT_CharMapRec    charmap;
        T1_CMap_Classes  cmap_classes = psaux->t1_cmap_classes;
        FT_CMap_Class    clazz;


        charmap.face = root;

        /* first of all, try to synthesize a Unicode charmap */
        charmap.platform_id = 3;
        charmap.encoding_id = 1;
        charmap.encoding    = FT_ENCODING_UNICODE;

        FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL );

        /* now, generate an Adobe Standard encoding when appropriate */
        charmap.platform_id = 7;
        clazz               = NULL;

        switch ( type1->encoding_type )
        {
        case T1_ENCODING_TYPE_STANDARD:
          charmap.encoding    = FT_ENCODING_ADOBE_STANDARD;
          charmap.encoding_id = 0;
          clazz               = cmap_classes->standard;
          break;

        case T1_ENCODING_TYPE_EXPERT:
          charmap.encoding    = FT_ENCODING_ADOBE_EXPERT;
          charmap.encoding_id = 1;
          clazz               = cmap_classes->expert;
          break;

        case T1_ENCODING_TYPE_ARRAY:
          charmap.encoding    = FT_ENCODING_ADOBE_CUSTOM;
          charmap.encoding_id = 2;
          clazz               = cmap_classes->custom;
          break;

        case T1_ENCODING_TYPE_ISOLATIN1:
          charmap.encoding    = FT_ENCODING_ADOBE_LATIN_1;
          charmap.encoding_id = 3;
          clazz               = cmap_classes->unicode;
          break;

        default:
          ;
        }

        if ( clazz )
          FT_CMap_New( clazz, NULL, &charmap, NULL );

#if 0
        /* Select default charmap */
        if ( root->num_charmaps )
          root->charmap = root->charmaps[0];
#endif
      }
    }
  Exit:
    return error;
  }
Beispiel #16
0
void xd::font::render(const std::string& text, const font_style& style,
	xd::shader_program::handle shader, const glm::mat4& mvp, glm::vec2 *pos)
{
	// check if we're rendering using this font or a linked font
	if (style.m_type && style.m_type->length() != 0) {
		font_map_t::iterator i = m_linked_fonts.find(*style.m_type);
		if (i == m_linked_fonts.end())
			throw invalid_font_type(*style.m_type);
		font_style linked_style = style;
		linked_style.m_type = boost::none;
		i->second->render(text, linked_style, shader, mvp, pos);
		return;
	}

	// check if the font size is already loaded
	auto it = m_face->sizes.find(style.m_size);
	if (it == m_face->sizes.end()) {
		// create a new size
		FT_Size size;
		if (FT_New_Size(m_face->handle, &size) != 0)
			throw font_load_failed(m_filename);
		// free the size in catch block if something goes wrong
		try {
			if (FT_Activate_Size(size) != 0)
				throw font_load_failed(m_filename);
			// set the pixel size
			if (FT_Set_Pixel_Sizes(m_face->handle, 0, style.m_size) != 0)
				throw font_load_failed(m_filename);
			// pre-load 7-bit ASCII glyphs
			for (int i = 0; i < 128; i++) {
				load_glyph(i, style.m_size);
			}
		} catch (...) {
			// free the size and re-throw
			FT_Done_Size(size);
			throw;
		}
		// insert the newly loaded size in the map
		m_face->sizes.insert(std::make_pair(style.m_size, size));
	} else {
		// activate the size
		FT_Activate_Size(it->second);
	}

	// bind to first texture unit
	glActiveTexture(GL_TEXTURE0);

	// setup the shader
	shader->use();
	shader->bind_uniform(m_mvp_uniform, mvp);
	shader->bind_uniform(m_color_uniform, style.m_color);
	shader->bind_uniform(m_texture_uniform, 0);

	// is kerning supported
	FT_Bool kerning = FT_HAS_KERNING(m_face->handle);

	// render each glyph in the string
	glm::vec2 text_pos;
	if (pos)
		text_pos = *pos;

	FT_UInt prev_glyph_index = 0;
	auto i = text.begin();
	while (i != text.end()) {
		// get the unicode code point
		utf8::uint32_t char_index = utf8::next(i, text.end());

		// get the cached glyph, or cache if it is not yet cached
		const detail::font::glyph& glyph = load_glyph(char_index, style.m_size);

		// bind the texture
		glBindTexture(GL_TEXTURE_2D, glyph.texture_id);

		// check for kerning
		if (kerning && glyph.glyph_index && prev_glyph_index) {
			FT_Vector kerning_delta;
			FT_Get_Kerning(m_face->handle, prev_glyph_index, glyph.glyph_index, FT_KERNING_DEFAULT, &kerning_delta);
			text_pos.x += kerning_delta.x >> 6;
		}

		// calculate exact offset
		glm::vec2 glyph_pos = text_pos;
		glyph_pos.x += glyph.offset.x;
		glyph_pos.y += glyph.offset.y;

		// add optional letter spacing
		glyph_pos.x += style.m_letter_spacing/2;

		// if shadow is enabled, draw the shadow first
		if (style.m_shadow) {
			// calculate shadow position
			glm::vec2 shadow_pos = glyph_pos;
			shadow_pos.x += style.m_shadow->x;
			shadow_pos.y += style.m_shadow->y;

			// calculate shadow color
			glm::vec4 shadow_color = style.m_shadow->color;
			shadow_color.a *= style.m_color.a;

			// bind uniforms
			shader->bind_uniform(m_color_uniform, shadow_color);
			shader->bind_uniform(m_position_uniform, shadow_pos);

			// draw shadow
			glyph.quad_ptr->render();

			// restore the text color
			shader->bind_uniform(m_color_uniform, style.m_color);
		}
		
		// if outline is enabled, draw outline
		if (style.m_outline) {
			// calculate outline color
			glm::vec4 outline_color = style.m_outline->color;
			outline_color.a *= style.m_color.a;

			// bind color
			shader->bind_uniform(m_color_uniform, outline_color);

			// draw font multiple times times to draw outline (EXPENSIVE!)
			for (int x = -style.m_outline->width; x <= style.m_outline->width; x++) {
				for (int y = -style.m_outline->width; y <= style.m_outline->width; y++) {
					if (x == 0 && y == 0)
						continue;
					shader->bind_uniform(m_position_uniform, glyph_pos + glm::vec2(x, y));
					glyph.quad_ptr->render();
				}
			}

			// restore the text color
			shader->bind_uniform(m_color_uniform, style.m_color);
		}

		// bind uniforms
		shader->bind_uniform(m_position_uniform, glyph_pos);

		// draw the glyph
		glyph.quad_ptr->render();
		
		// advance the position
		text_pos += glyph.advance;
		text_pos.x += style.m_letter_spacing;

		// keep track of previous glyph to do kerning
		prev_glyph_index = glyph.glyph_index;
	}
Beispiel #17
0
  T42_Face_Init( FT_Stream      stream,
                 T42_Face       face,
                 FT_Int         face_index,
                 FT_Int         num_params,
                 FT_Parameter*  params )
  {
    FT_Error          error;
    PSNames_Service   psnames;
    PSAux_Service     psaux;
    FT_Face           root    = (FT_Face)&face->root;

    FT_UNUSED( num_params );
    FT_UNUSED( params );
    FT_UNUSED( face_index );
    FT_UNUSED( stream );


    face->ttf_face       = NULL;
    face->root.num_faces = 1;

    face->psnames = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),
                                             "psnames" );
    psnames = (PSNames_Service)face->psnames;

    face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),
                                           "psaux" );
    psaux = (PSAux_Service)face->psaux;

    /* open the tokenizer, this will also check the font format */
    error = T42_Open_Face( face );
    if ( error )
      goto Exit;

    /* if we just wanted to check the format, leave successfully now */
    if ( face_index < 0 )
      goto Exit;

    /* check the face index */
    if ( face_index != 0 )
    {
      FT_ERROR(( "T42_Face_Init: invalid face index\n" ));
      error = T42_Err_Invalid_Argument;
      goto Exit;
    }

    /* Now, load the font program into the face object */

    /* Init the face object fields */
    /* Now set up root face fields */

    root->num_glyphs   = face->type1.num_glyphs;
    root->num_charmaps = 0;
    root->face_index   = face_index;

    root->face_flags  = FT_FACE_FLAG_SCALABLE;
    root->face_flags |= FT_FACE_FLAG_HORIZONTAL;
    root->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;

    if ( face->type1.font_info.is_fixed_pitch )
      root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;

    /* XXX: TODO -- add kerning with .afm support */

    /* get style name -- be careful, some broken fonts only */
    /* have a `/FontName' dictionary entry!                 */
    root->family_name = face->type1.font_info.family_name;
    if ( root->family_name )
    {
      char*  full   = face->type1.font_info.full_name;
      char*  family = root->family_name;


      if ( full )
      {
        while ( *family && *full == *family )
        {
          family++;
          full++;
        }

        root->style_name = ( *full == ' ' ? full + 1
                                          : (char *)"Regular" );
      }
      else
        root->style_name = (char *)"Regular";
    }
    else
    {
      /* do we have a `/FontName'? */
      if ( face->type1.font_name )
      {
        root->family_name = face->type1.font_name;
        root->style_name  = (char *)"Regular";
      }
    }

    /* no embedded bitmap support */
    root->num_fixed_sizes = 0;
    root->available_sizes = 0;

    /* Load the TTF font embedded in the T42 font */
    error = FT_New_Memory_Face( FT_FACE_LIBRARY( face ),
                                face->ttf_data,
                                face->ttf_size,
                                0,
                                &face->ttf_face );
    if ( error )
      goto Exit;

    FT_Done_Size( face->ttf_face->size );

    /* Ignore info in FontInfo dictionary and use the info from the  */
    /* loaded TTF font.  The PostScript interpreter also ignores it. */
    root->bbox         = face->ttf_face->bbox;
    root->units_per_EM = face->ttf_face->units_per_EM;

    root->ascender  = face->ttf_face->ascender;
    root->descender = face->ttf_face->descender;
    root->height    = face->ttf_face->height;

    root->max_advance_width  = face->ttf_face->max_advance_width;
    root->max_advance_height = face->ttf_face->max_advance_height;

    root->underline_position  = face->type1.font_info.underline_position;
    root->underline_thickness = face->type1.font_info.underline_thickness;

    root->internal->max_points   = 0;
    root->internal->max_contours = 0;

    /* compute style flags */
    root->style_flags = 0;
    if ( face->type1.font_info.italic_angle )
      root->style_flags |= FT_STYLE_FLAG_ITALIC;

    if ( face->ttf_face->style_flags & FT_STYLE_FLAG_BOLD )
      root->style_flags |= FT_STYLE_FLAG_BOLD;

    if ( face->ttf_face->face_flags & FT_FACE_FLAG_VERTICAL )
      root->face_flags |= FT_FACE_FLAG_VERTICAL;

    {
      if ( psnames && psaux )
      {
        FT_CharMapRec    charmap;
        T1_CMap_Classes  cmap_classes = psaux->t1_cmap_classes;
        FT_CMap_Class    clazz;


        charmap.face = root;

        /* first of all, try to synthetize a Unicode charmap */
        charmap.platform_id = 3;
        charmap.encoding_id = 1;
        charmap.encoding    = FT_ENCODING_UNICODE;

        FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL );

        /* now, generate an Adobe Standard encoding when appropriate */
        charmap.platform_id = 7;
        clazz               = NULL;

        switch ( face->type1.encoding_type )
        {
        case T1_ENCODING_TYPE_STANDARD:
          charmap.encoding    = FT_ENCODING_ADOBE_STANDARD;
          charmap.encoding_id = 0;
          clazz               = cmap_classes->standard;
          break;

        case T1_ENCODING_TYPE_EXPERT:
          charmap.encoding    = FT_ENCODING_ADOBE_EXPERT;
          charmap.encoding_id = 1;
          clazz               = cmap_classes->expert;
          break;

        case T1_ENCODING_TYPE_ARRAY:
          charmap.encoding    = FT_ENCODING_ADOBE_CUSTOM;
          charmap.encoding_id = 2;
          clazz               = cmap_classes->custom;
          break;

        case T1_ENCODING_TYPE_ISOLATIN1:
          charmap.encoding    = FT_ENCODING_ADOBE_LATIN_1;
          charmap.encoding_id = 3;
          clazz               = cmap_classes->unicode;
          break;

        default:
          ;
        }

        if ( clazz )
          FT_CMap_New( clazz, NULL, &charmap, NULL );

#if 0
        /* Select default charmap */
        if (root->num_charmaps)
          root->charmap = root->charmaps[0];
#endif
      }
    }
  Exit:
    return error;
  }
Beispiel #18
0
static Font_Info *
_font_slave_int_load(const Slave_Msg_Font_Load *msg, Font_Source_Info *fsi)
{
   int error;
   int val, dv;
   int ret;
   Font_Info *fi = calloc(1, sizeof(*fi));

   error = FT_New_Size(fsi->face, &(fi->size));
   if (!error)
     FT_Activate_Size(fi->size);

   fi->fsize = msg->size;
   fi->dpi = msg->dpi;
   fi->real_size = msg->size * 64;
   fi->fsi = fsi;
   error = FT_Set_Char_Size(fsi->face, 0, fi->real_size, msg->dpi, msg->dpi);
   if (error)
     error = FT_Set_Pixel_Sizes(fsi->face, 0, fi->real_size);

   if (error)
     {
        int i, maxd = 0x7fffffff;
        int chosen_size = 0;
        int chosen_size2 = 0;

        for (i = 0; i < fsi->face->num_fixed_sizes; i++)
          {
             int s, cd;

             s = fsi->face->available_sizes[i].size;
             cd = chosen_size - fi->real_size;
             if (cd < 0) cd = -cd;
             if (cd < maxd)
               {
                  maxd = cd;
                  chosen_size = s;
                  chosen_size2 = fsi->face->available_sizes[i].y_ppem;
                  if (maxd == 0) break;
               }
          }
        fi->real_size = chosen_size;
        error = FT_Set_Pixel_Sizes(fsi->face, 0, fi->real_size);

        if (error)
          {
             error = FT_Set_Char_Size(fsi->face, 0, fi->real_size, fi->dpi, fi->dpi);
             if (error)
               {
                  /* hack around broken fonts */
                  fi->real_size = (chosen_size2 / 64) * 60;
                  error = FT_Set_Char_Size(fsi->face, 0, fi->real_size, fi->dpi, fi->dpi);
                  if (error)
                    {
                       ERR("Could not choose the font size for font: '%s:%s'.",
                           msg->file, msg->name);
                       FT_Done_Size(fi->size);
                       free(fi);
                       return NULL;
                    }
               }
          }
     }

   fi->max_h = 0;
   val = (int)fsi->face->bbox.yMax;
   if (fsi->face->units_per_EM != 0)
     {
        dv = (fsi->orig_upem * 2048) / fsi->face->units_per_EM;
        ret = (val * fsi->face->size->metrics.y_scale) / (dv * dv);
     }
   else ret = val;
   fi->max_h += ret;
   val = -(int)fsi->face->bbox.yMin;
   if (fsi->face->units_per_EM != 0)
     {
        dv = (fsi->orig_upem * 2048) / fsi->face->units_per_EM;
        ret = (val * fsi->face->size->metrics.y_scale) / (dv * dv);
     }
   else ret = val;
   fi->max_h += ret;

   fi->runtime_rend = FONT_REND_REGULAR;
   if ((msg->rend_flags & FONT_REND_SLANT) &&
       !(fsi->face->style_flags & FT_STYLE_FLAG_ITALIC))
     fi->runtime_rend |= FONT_REND_SLANT;
   if ((msg->rend_flags & FONT_REND_WEIGHT) &&
       !(fsi->face->style_flags & FT_STYLE_FLAG_BOLD))
     fi->runtime_rend |= FONT_REND_WEIGHT;

   return fi;
}