Esempio n. 1
0
font::font(Window* window){
  parentWindow = window;
  shader = new Shader(window);
  shader->load(shadersPath + "text.vert", shadersPath + "text.frag", "");
  glUseProgram(shader->ID);

  // FreeType
  FT_Library ft;
  // All functions return a value different than 0 whenever an error occurred
  if (FT_Init_FreeType(&ft))
    std::cout << "ERROR::FREETYPE: Could not init FreeType Library" << std::endl;
  // Load font as face
  FT_Face face;
  if (FT_New_Face(ft, "../fonts/arial.ttf", 0, &face))
    std::cout << "ERROR::FREETYPE: Failed to load font" << std::endl;
  // Set size to load glyphs as
  FT_Set_Pixel_Sizes(face, 0, 48);
  // Disable byte-alignment restriction
  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  // Load first 128 characters of ASCII set
  for (GLubyte c = 0; c < 128; c++){
    // Load character glyph
    if (FT_Load_Char(face, c, FT_LOAD_RENDER)){
      std::cout << "ERROR::FREETYTPE: Failed to load Glyph" << std::endl;
      continue;
    }
    // Generate texture
    GLuint texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(
		 GL_TEXTURE_2D,
		 0,
		 GL_RED,
		 face->glyph->bitmap.width,
		 face->glyph->bitmap.rows,
		 0,
		 GL_RED,
		 GL_UNSIGNED_BYTE,
		 face->glyph->bitmap.buffer
		 );
    // Set texture options
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    // Now store character for later use
    Character character = {
      texture,
      glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
      glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
      (GLuint)face->glyph->advance.x
    };
    Characters.insert(std::pair<GLchar, Character>(c, character));
  }
  glBindTexture(GL_TEXTURE_2D, 0);
  // Destroy FreeType once we're finished
  FT_Done_Face(face);
  FT_Done_FreeType(ft);

  // Configure VAO/VBO for texture quads
  glGenVertexArrays(1, &VAO);
  glGenBuffers(1, &VBO);
  glBindVertexArray(VAO);
  glBindBuffer(GL_ARRAY_BUFFER, VBO);
  glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
  glEnableVertexAttribArray(0);
  glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
  glBindBuffer(GL_ARRAY_BUFFER, 0);
  glBindVertexArray(0);
}
Esempio n. 2
0
gfxfont_t* gfxfont_load(const char*id, const char*filename, unsigned int flags, double quality)
{
    FT_Face face;
    FT_Error error;
    const char* fontname = 0;
    FT_ULong charcode;
    FT_UInt gindex;
    gfxfont_t* font;
    int t;
    int*glyph2glyph = 0;
    int*glyph2unicode = 0;
    int max_unicode = 0;
    int charmap = -1;
    int isunicode = 1;
    int has_had_errors = 0;
    int num_names = 0;

    if(ftlibrary == 0) {
	if(FT_Init_FreeType(&ftlibrary)) {
	    fprintf(stderr, "Couldn't init freetype library!\n");
	    exit(1);
	}
    }
    error = FT_New_Face(ftlibrary, filename, 0, &face);
    FT_Set_Pixel_Sizes (face, 16*loadfont_scale, 16*loadfont_scale);
#ifdef DEBUG
    printf("gfxfont_load(%s, %s, %f)\n", id, filename, quality);
#endif

    if(error) {
	fprintf(stderr, "Couldn't load file %s- not a TTF file? (error=%02x)\n", filename, error);
	return 0;
    }
    if(face->num_glyphs <= 0) {
	fprintf(stderr, "File %s contains %d glyphs\n", filename, (int)face->num_glyphs);
	return 0;
    }

    font = (gfxfont_t*)rfx_calloc(sizeof(gfxfont_t));
    //font->style =  ((face->style_flags&FT_STYLE_FLAG_ITALIC)?FONT_STYLE_ITALIC:0) |((face->style_flags&FT_STYLE_FLAG_BOLD)?FONT_STYLE_BOLD:0);
    //font->ascent = abs(face->ascender)*FT_SCALE*loadfont_scale*20/FT_SUBPIXELS/2; //face->bbox.xMin;
    //font->descent = abs(face->descender)*FT_SCALE*loadfont_scale*20/FT_SUBPIXELS/2; //face->bbox.xMax;
    //font->leading = font->layout->ascent + font->layout->descent;
    //font->encoding = FONT_ENCODING_UNICODE;
    font->max_unicode = 0;
    font->id = strdup(id);
    
    font->glyphs = (gfxglyph_t*)rfx_calloc(face->num_glyphs*sizeof(gfxglyph_t));
    glyph2unicode = (int*)rfx_calloc(face->num_glyphs*sizeof(int));
    glyph2glyph = (int*)rfx_calloc(face->num_glyphs*sizeof(int));

    if(FT_HAS_GLYPH_NAMES(face)) {
	//font->glyphnames = rfx_calloc(face->num_glyphs*sizeof(char*));
    }

    fontname = FT_Get_Postscript_Name(face);

#ifdef DEBUG
    for(t=0;t<face->num_charmaps;t++) {
        printf("possible encoding: %c%c%c%c (%d of %d)\n", 
                (face->charmaps[t]->encoding >> 24)&255,
                (face->charmaps[t]->encoding >> 16)&255,
                (face->charmaps[t]->encoding >> 8)&255,
                (face->charmaps[t]->encoding >> 0)&255,
                t+1, face->num_charmaps
                );
    }
#endif

    while(1) 
    {
	charcode = FT_Get_First_Char(face, &gindex);

	while(gindex != 0)
	{
	    if(gindex >= 0 && gindex<face->num_glyphs) {
		if(!glyph2unicode[gindex]) {
		    glyph2unicode[gindex] = charcode;
		    if(charcode + 1 > font->max_unicode) {
			font->max_unicode = charcode + 1;
		    }
		}
	    }
	    charcode = FT_Get_Next_Char(face, charcode, &gindex);
	}

#ifdef DEBUG
        if(face->charmap) {
            printf("ENCODING: %c%c%c%c (%d of %d) max_unicode=%d\n", 
                    (face->charmap->encoding >> 24)&255,
                    (face->charmap->encoding >> 16)&255,
                    (face->charmap->encoding >> 8)&255,
                    (face->charmap->encoding >> 0)&255,
                    charmap, face->num_charmaps, font->max_unicode
                    );
        } else {
Esempio n. 3
0
/*!
	\brief Scan a folder for all valid fonts
	\param fontspath Path of the folder to scan.
	\return 
	- \c B_OK				Success
	- \c B_NAME_TOO_LONG	The path specified is too long
	- \c B_ENTRY_NOT_FOUND	The path does not exist
	- \c B_LINK_LIMIT		A cyclic loop was detected in the file system
	- \c B_BAD_VALUE		Invalid input specified
	- \c B_NO_MEMORY		Insufficient memory to open the folder for reading
	- \c B_BUSY				A busy node could not be accessed
	- \c B_FILE_ERROR		An invalid file prevented the operation.
	- \c B_NO_MORE_FDS		All file descriptors are in use (too many open files). 
*/
status_t FontServer::ScanDirectory(const char *fontspath)
{
	// This bad boy does all the real work. It loads each entry in the
	// directory. If a valid font file, it adds both the family and the style.
	// Both family and style are stored internally as BStrings. Once everything

	int32 validcount=0;
    FT_Face  face;
    FT_Error error;
    FT_CharMap charmap;
    FontFamily *family;

	DIR*        hDir;
	dirent*        psEntry;

	printf( "FontServer::ScanDirectory(): opening %s\n", fontspath );

	if ( (hDir = opendir( fontspath ) ) )
	{
		while( (psEntry = readdir( hDir )) )
		{
			printf( "FontServer::ScanDirectory(): found entry %s\n", psEntry->d_name );
			char     zFullPath[ PATH_MAX ];

			if ( strcmp( psEntry->d_name, "." ) == 0 || strcmp( psEntry->d_name, ".." ) == 0 )
			{
				continue;
			}
			strcpy( zFullPath, fontspath );
			pathcat( zFullPath, psEntry->d_name );

			error=FT_New_Face(ftlib, zFullPath,0,&face);

			if (error!=0)
				continue;

			charmap=_GetSupportedCharmap(face);
			if(!charmap)
			{
				FT_Done_Face(face);
				continue;
			}

			face->charmap=charmap;

			family=_FindFamily(face->family_name );

			if (!family)
			{
				#ifdef PRINT_FONT_LIST
				printf("Font Family: %s\n",face->family_name);
				#endif

				family=new FontFamily(face->family_name);
				families->AddItem(family);
			}

			if(family->HasStyle(face->style_name))
			{
				FT_Done_Face(face);
				continue;
			}

			#ifdef PRINT_FONT_LIST
			printf("\tFont Style: %s\n",face->style_name);
			#endif

			// Has vertical metrics?
			family->AddStyle(zFullPath,face);
			validcount++;

			FT_Done_Face(face);
		}
		printf( "Directory '%s' scanned, %ld fonts found\n", fontspath, validcount );
		closedir( hDir );
	}

	need_update=true;
	return B_OK;
}
Esempio n. 4
0
unsigned char *gks_ft_get_bitmap(int *x, int *y, int *width, int *height,
                                 gks_state_list_t *gkss, const char *text,
                                 int length) {
  FT_Face face;                   /* font face */
  FT_Vector pen;                  /* glyph position */
  FT_BBox bb;                     /* bounding box */
  FT_Vector bearing;              /* individual glyph translation */
  FT_UInt previous;               /* previous glyph index */
  FT_Vector spacing;              /* amount of additional space between glyphs */
  FT_ULong textheight;            /* textheight in FreeType convention */
  FT_Error error;                 /* error code */
  FT_Matrix rotation;             /* text rotation matrix */
  FT_UInt size;                   /* number of pixels of the bitmap */
  FT_String *file;                /* concatenated font path */
  const FT_String *font, *prefix; /* font file name and directory */
  FT_UInt *unicode_string;        /* unicode text string */
  FT_Int halign, valign;          /* alignment */
  FT_Byte *mono_bitmap = NULL;    /* target for rendered text */
  FT_Int num_glyphs;              /* number of glyphs */
  FT_Vector align;
  FT_Bitmap ftbitmap;
  FT_UInt codepoint;
  int i, textfont, dx, dy, value, pos_x, pos_y;
  unsigned int j, k;
  double angle;
  const int windowwidth = *width;
  const int direction = (gkss->txp <= 3 && gkss->txp >= 0 ? gkss->txp : 0);
  const FT_Bool vertical = (direction == GKS_K_TEXT_PATH_DOWN ||
                            direction == GKS_K_TEXT_PATH_UP);
  const FT_String *suffix_type1 = ".afm";

  if (!init) gks_ft_init();

  if (gkss->txal[0] != GKS_K_TEXT_HALIGN_NORMAL) {
    halign = gkss->txal[0];
  } else if (vertical) {
    halign = GKS_K_TEXT_HALIGN_CENTER;
  } else if (direction == GKS_K_TEXT_PATH_LEFT) {
    halign = GKS_K_TEXT_HALIGN_RIGHT;
  } else {
    halign = GKS_K_TEXT_HALIGN_LEFT;
  }
  valign = gkss->txal[1];
  if (valign != GKS_K_TEXT_VALIGN_NORMAL) {
    valign = gkss->txal[1];
  } else {
    valign = GKS_K_TEXT_VALIGN_BASE;
  }

  textfont = abs(gkss->txfont);
  if (textfont >= 101 && textfont <= 131)
    textfont -= 100;
  else if (textfont > 1 && textfont <= 32)
    textfont = map[textfont - 1];
  else
    textfont = 9;

  textfont = textfont - 1;
  font = gks_font_list[textfont];

  if (font_face_cache[textfont] == NULL) {
    prefix = gks_getenv("GKS_FONTPATH");
    if (prefix == NULL) {
      prefix = gks_getenv("GRDIR");
      if (prefix == NULL)
        prefix = GRDIR;
    }
    file = (FT_String *) malloc(strlen(prefix) + 7 + strlen(font) + 4 + 1);
    strcpy(file, prefix);
#ifndef _WIN32
    strcat(file, "/fonts/");
#else
    strcat(file, "\\FONTS\\");
#endif
    strcat(file, font);
    strcat(file, ".pfb");
    error = FT_New_Face(library, file, 0, &face);
    if (error == FT_Err_Unknown_File_Format) {
      gks_perror("unknown file format: %s", file);
      return NULL;
    } else if (error) {
      gks_perror("could not open font file: %s", file);
      return NULL;
    }
    if (strcmp(FT_Get_X11_Font_Format(face), "Type 1") == 0) {
      strcpy(file, prefix);
#ifndef _WIN32
      strcat(file, "/fonts/");
#else
      strcat(file, "\\FONTS\\");
#endif
      strcat(file, font);
      strcat(file, suffix_type1);
      FT_Attach_File(face, file);
    }
    free(file);
    font_face_cache[textfont] = face;
  } else {
    face = font_face_cache[textfont];
  }

  num_glyphs = length;
  unicode_string = (FT_UInt *) malloc(length * sizeof(FT_UInt) + 1);
  if (textfont + 1 == 13) {
    symbol_to_unicode((FT_Bytes)text, unicode_string, num_glyphs);
  } else {
    utf_to_unicode((FT_Bytes)text, unicode_string, &num_glyphs);
  }

  textheight = nint(gkss->chh * windowwidth * 64 / caps[textfont]);
  error = FT_Set_Char_Size(face, nint(textheight * gkss->chxp), textheight,
                           72, 72);
  if (error) gks_perror("cannot set text height");

  if (gkss->chup[0] != 0.0 || gkss->chup[1] != 0.0) {
    angle = atan2f(gkss->chup[1], gkss->chup[0]) - M_PI / 2;
    rotation.xx = nint( cosf(angle) * 0x10000L);
    rotation.xy = nint(-sinf(angle) * 0x10000L);
    rotation.yx = nint( sinf(angle) * 0x10000L);
    rotation.yy = nint( cosf(angle) * 0x10000L);
    FT_Set_Transform(face, &rotation, NULL);
  } else {
    FT_Set_Transform(face, NULL, NULL);
  }

  spacing.x = spacing.y = 0;
  if (gkss->chsp != 0.0) {
    error = FT_Load_Glyph(face, FT_Get_Char_Index(face, ' '),
                          vertical ? FT_LOAD_VERTICAL_LAYOUT : FT_LOAD_DEFAULT);
    if (!error) {
      spacing.x = nint(face->glyph->advance.x * gkss->chsp);
      spacing.y = nint(face->glyph->advance.y * gkss->chsp);
    } else {
      gks_perror("cannot apply character spacing");
    }
  }

  bb.xMin = bb.yMin = LONG_MAX;
  bb.xMax = bb.yMax = LONG_MIN;
  pen.x = pen.y = 0;
  previous = 0;

  for (i = 0; i < num_glyphs; i++) {
    codepoint = unicode_string[direction == GKS_K_TEXT_PATH_LEFT ?
                               (num_glyphs - 1 - i) : i];
    error = set_glyph(face, codepoint, &previous, &pen, vertical, &rotation,
                      &bearing, halign);
    if (error) continue;

    bb.xMin = ft_min(bb.xMin, pen.x + bearing.x);
    bb.xMax = ft_max(bb.xMax, pen.x + bearing.x + 64*face->glyph->bitmap.width);
    bb.yMin = ft_min(bb.yMin, pen.y + bearing.y - 64*face->glyph->bitmap.rows);
    bb.yMax = ft_max(bb.yMax, pen.y + bearing.y);

    if (direction == GKS_K_TEXT_PATH_DOWN) {
      pen.x -= face->glyph->advance.x + spacing.x;
      pen.y -= face->glyph->advance.y + spacing.y;
    } else {
      pen.x += face->glyph->advance.x + spacing.x;
      pen.y += face->glyph->advance.y + spacing.y;
    }
  }
  *width  = (int)((bb.xMax - bb.xMin) / 64);
  *height = (int)((bb.yMax - bb.yMin) / 64);
  if (bb.xMax <= bb.xMin || bb.yMax <= bb.yMin) {
    gks_perror("invalid bitmap size");
    free(unicode_string);
    return NULL;
  }
  size = *width * *height;
  mono_bitmap = (FT_Byte *) safe_realloc(mono_bitmap, size);
  memset(mono_bitmap, 0, size);

  pen.x = 0;
  pen.y = 0;
  previous = 0;

  for (i = 0; i < num_glyphs; i++) {
    bearing.x = bearing.y = 0;
    codepoint = unicode_string[direction == GKS_K_TEXT_PATH_LEFT ?
                               (num_glyphs - 1 - i) : i];
    error = set_glyph(face, codepoint, &previous, &pen, vertical, &rotation,
                      &bearing, halign);
    if (error) continue;

    pos_x = ( pen.x + bearing.x - bb.xMin) / 64;
    pos_y = (-pen.y - bearing.y + bb.yMax) / 64;
    ftbitmap = face->glyph->bitmap;
    for (j = 0; j < (unsigned int) ftbitmap.rows; j++) {
      for (k = 0; k < (unsigned int) ftbitmap.width; k++) {
        dx = k + pos_x;
        dy = j + pos_y;
        value = mono_bitmap[dy * *width + dx];
        value += ftbitmap.buffer[j * ftbitmap.pitch + k];
        if (value > 255) {
          value = 255;
        }
        mono_bitmap[dy * *width + dx] = value;
      }
    }

    if (direction == GKS_K_TEXT_PATH_DOWN) {
      pen.x -= face->glyph->advance.x + spacing.x;
      pen.y -= face->glyph->advance.y + spacing.y;
    } else {
      pen.x += face->glyph->advance.x + spacing.x;
      pen.y += face->glyph->advance.y + spacing.y;
    }
  }
  free(unicode_string);

  /* Alignment */
  if (direction == GKS_K_TEXT_PATH_DOWN) {
    pen.x += spacing.x;
    pen.y += spacing.y;
  } else {
    pen.x -= spacing.x;
    pen.y -= spacing.y;
  }

  align.x = align.y = 0;
  if (valign != GKS_K_TEXT_VALIGN_BASE) {
    align.y = nint(gkss->chh * windowwidth * 64);
    FT_Vector_Transform(&align, &rotation);
    if (valign == GKS_K_TEXT_VALIGN_HALF) {
      align.x = nint(0.5 * align.x);
      align.y = nint(0.5 * align.y);
    } else if (valign == GKS_K_TEXT_VALIGN_TOP) {
      align.x = nint(1.2 * align.x);
      align.y = nint(1.2 * align.y);
    } else if (valign == GKS_K_TEXT_VALIGN_BOTTOM) {
      align.x = nint(-0.2 * align.x);
      align.y = nint(-0.2 * align.y);
    }
  }

  if (!vertical && halign != GKS_K_TEXT_HALIGN_LEFT) {
    FT_Vector right;
    right.x = face->glyph->metrics.width + face->glyph->metrics.horiBearingX;
    right.y = 0;
    if (right.x != 0) {
      FT_Vector_Transform(&right, &rotation);
    }
    pen.x += right.x - face->glyph->advance.x;
    pen.y += right.y - face->glyph->advance.y;
    if (halign == GKS_K_TEXT_HALIGN_CENTER) {
      align.x += pen.x / 2;
      align.y += pen.y / 2;
    } else if (halign == GKS_K_TEXT_HALIGN_RIGHT) {
      align.x += pen.x;
      align.y += pen.y;
    }
  }

  *x += (bb.xMin - align.x) / 64;
  *y += (bb.yMin - align.y) / 64;
  return mono_bitmap;
}
Esempio n. 5
0
void drawIndicText(JNIEnv *env, jobject thiz, jstring unicodeText, jint xStart,
				   jint yBaseLine, jint charHeight, jobject lock, jstring fontPath, jint language) {
	FT_Library ft_library;
	FT_Face ft_face;

	hb_font_t *font;
	hb_buffer_t *buffer;
	int glyph_count;
	hb_glyph_info_t *glyph_info;
	hb_glyph_position_t *glyph_pos;
	hb_bool_t fail;

	FT_UInt glyph_index;
	FT_GlyphSlot slot;
	FT_Error error;


	jboolean iscopy;
	const jchar *text;
	int num_chars, i;

	int pen_x;
	int glyphPosX, glyphPosY;

	const char *fontFilePath = (*env)->GetStringUTFChars(env, fontPath, NULL);


	text = (*env)->GetStringChars(env, unicodeText, &iscopy);
	num_chars = (*env)->GetStringLength(env, unicodeText);

	/* initialize library */
	error = FT_Init_FreeType(&ft_library);
	if (error) {
		__android_log_print(6, "drawIndicText",
							"Error initializing FreeType library\n");
		return;
	}
	// __android_log_print(2, "drawIndicText",
	//	    "Successfully initialized FreeType library\n");

	error = FT_New_Face(ft_library, fontFilePath, 0, &ft_face); /* create face object */
	if (error == FT_Err_Unknown_File_Format) {
		__android_log_print(6, "drawIndicText",
							"The font file could be opened and read, but it appears that its font format is unsupported %s ",
							fontFilePath);
		return;
	} else if (error) {
		__android_log_print(6, "drawIndicText",
							"The font file could not be opened or read, or it might be broken");
		return;
	}
	// __android_log_print(2, "drawIndicText",
	//	    "Successfully created font-face object\n");

	font = hb_ft_font_create(ft_face, NULL);

	error = FT_Set_Pixel_Sizes(ft_face, 0, charHeight); /* set character size */

	slot = ft_face->glyph;
	pen_x = xStart;

	/* Create a buffer for harfbuzz to use */
	buffer = hb_buffer_create();

	hb_buffer_set_script(buffer, scripts[language]);

	/* Layout the text */
	hb_buffer_add_utf16(buffer, text, num_chars, 0, num_chars);
	// __android_log_print(2, "drawIndicText", "Before HarfBuzz shape()\n");

	hb_shape(font, buffer, NULL, 0);
	// __android_log_print(2, "drawIndicText", "After HarfBuzz shape()\n");

	glyph_count = hb_buffer_get_length(buffer);
	glyph_info = hb_buffer_get_glyph_infos(buffer, 0);
	glyph_pos = hb_buffer_get_glyph_positions(buffer, 0);

	for (i = 0; i < glyph_count; i++) {
		glyph_index = glyph_info[i].codepoint;

		// __android_log_print(2, "drawIndicText", "Glyph%d = %x", i, glyph_index);

		error = FT_Load_Glyph(ft_face, glyph_index, FT_LOAD_DEFAULT);
		if (error) {
			/* ignore errors */
			continue;
		}

		/* convert to an anti-aliased bitmap */
		error = FT_Render_Glyph(ft_face->glyph, FT_RENDER_MODE_NORMAL);
		if (error) {
			continue;
		}

		/* now, draw to our target surface (convert position) */
		draw_bitmap(&slot->bitmap, pen_x + slot->bitmap_left,
					yBaseLine - slot->bitmap_top, env, thiz, lock);

		/* increment pen position */
		pen_x += slot->advance.x >> 6;
	}

	hb_buffer_destroy(buffer);

	(*env)->ReleaseStringChars(env, unicodeText, text);
	(*env)->ReleaseStringUTFChars(env, fontPath, fontFilePath);
	hb_font_destroy(font);
	FT_Done_Face(ft_face);
	FT_Done_FreeType(ft_library);

	return;
}
Esempio n. 6
0
static Bool ft_enum_fonts(void *cbck, char *file_name, char *file_path, GF_FileEnumInfo *file_info)
{
    char *szfont;
    FT_Face face;
    u32 num_faces, i;
    GF_FontReader *dr = cbck;
    FTBuilder *ftpriv = dr->udta;

    GF_LOG(GF_LOG_DEBUG, GF_LOG_PARSER, ("[FreeType] Enumerating font %s (%s)\n", file_name, file_path));

    if (FT_New_Face(ftpriv->library, file_path, 0, & face )) return 0;
    if (!face || !face->family_name) return 0;

    num_faces = face->num_faces;
    /*locate right font in collection if several*/
    for (i=0; i<num_faces; i++) {

        /*only scan scalable fonts*/
        if (face->face_flags & FT_FACE_FLAG_SCALABLE) {
            Bool bold, italic;
            szfont = gf_malloc(sizeof(char)* (strlen(face->family_name)+100));
            if (!szfont) continue;
            strcpy(szfont, face->family_name);

            /*remember first font found which looks like a alphabetical one*/
            if (!ftpriv->font_dir) {
                u32 gidx;
                FT_Select_Charmap(face, FT_ENCODING_UNICODE);
                gidx = FT_Get_Char_Index(face, (u32) 'a');
                if (gidx) gidx = FT_Get_Char_Index(face, (u32) 'z');
                if (gidx) gidx = FT_Get_Char_Index(face, (u32) '1');
                if (gidx) gidx = FT_Get_Char_Index(face, (u32) '@');
                if (gidx) ftpriv->font_dir = gf_strdup(szfont);
            }

            bold = italic = 0;

            if (face->style_name) {
                char *name = gf_strdup(face->style_name);
                strupr(name);
                if (strstr(name, "BOLD")) bold = 1;
                if (strstr(name, "ITALIC")) italic = 1;
                /*if font is not regular style, append all styles blindly*/
                if (!strstr(name, "REGULAR")) {
                    strcat(szfont, " ");
                    strcat(szfont, face->style_name);
                }
                gf_free(name);
            } else {
                if (face->style_flags & FT_STYLE_FLAG_BOLD) bold = 1;
                if (face->style_flags & FT_STYLE_FLAG_ITALIC) italic = 1;

                if (bold) strcat(szfont, " Bold");
                if (italic) strcat(szfont, " Italic");
            }
            gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", szfont, file_path);

            /*try to assign default fixed fonts*/
            if (!bold && !italic) {
                strcpy(szfont, face->family_name);
                strlwr(szfont);

                if (face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) {
                    setBestFont(BEST_FIXED_FONTS, &(ftpriv->font_fixed), face->family_name);
                }
                setBestFont(BEST_SERIF_FONTS, &(ftpriv->font_serif), face->family_name);
                setBestFont(BEST_SANS_FONTS, &(ftpriv->font_sans), face->family_name);
            }
            gf_free(szfont);
        }

        FT_Done_Face(face);
        if (i+1==num_faces) return 0;

        /*load next font in collection*/
        if (FT_New_Face(ftpriv->library, file_path, i+1, & face )) return 0;
        if (!face) return 0;
    }
    return 0;
}
FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const AtomicString& familyName)
    : m_pattern(0)
    , m_size(fontDescription.computedSize())
    , m_syntheticBold(false)
    , m_syntheticOblique(false)
    , m_scaledFont(0)
    , m_face(0)
{
    FontPlatformData::init();

    CString familyNameString = familyName.string().utf8();
    const char* fcfamily = familyNameString.data();

    int fcslant = FC_SLANT_ROMAN;
    // FIXME: Map all FontWeight values to fontconfig weights.
    int fcweight = FC_WEIGHT_NORMAL;
    float fcsize = fontDescription.computedSize();
    if (fontDescription.italic())
        fcslant = FC_SLANT_ITALIC;
    if (fontDescription.weight() >= FontWeight600)
        fcweight = FC_WEIGHT_BOLD;

    FcConfig *config = FcConfigGetCurrent();

    //printf("family = %s\n", fcfamily);

    int type = fontDescription.genericFamily();

    FcPattern* pattern = FcPatternCreate();
    
    if (!FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily)))
        goto freePattern;

    switch (type) {
        case FontDescription::SerifFamily:
            fcfamily = "serif";
            break;
        case FontDescription::SansSerifFamily:
            fcfamily = "sans-serif";
            break;
        case FontDescription::MonospaceFamily:
            fcfamily = "monospace";
            break;
        case FontDescription::NoFamily:
        case FontDescription::StandardFamily:
        default:
            fcfamily = "sans-serif";
    }

    if (!FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily)))
        goto freePattern;
    if (!FcPatternAddInteger(pattern, FC_SLANT, fcslant))
        goto freePattern;
    if (!FcPatternAddInteger(pattern, FC_WEIGHT, fcweight))
        goto freePattern;
    if (!FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fcsize))
        goto freePattern;

    FcConfigSubstitute(config, pattern, FcMatchPattern);
    FcDefaultSubstitute(pattern);

    FcResult fcresult;
    m_pattern = FcFontMatch(config, pattern, &fcresult);
    FcPatternReference(m_pattern);
    // FIXME: should we set some default font?
    if (!m_pattern)
        goto freePattern;

    FcChar8 *fc_filename;
    char *filename;
    int id;
    id = 0;

    if (FcPatternGetString(m_pattern, FC_FILE, 0, &fc_filename) != FcResultMatch) {
        DS_WAR("cannot retrieve font\n");
        goto freePattern;
    }

    filename = (char *) fc_filename; //use C cast as FcChar is a fontconfig type
    //printf("filename = %s\n", filename);

    if (FcPatternGetInteger(m_pattern, FC_INDEX, 0, &id) != FcResultMatch) {
        DS_WAR("cannot retrieve font index\n");
        goto freePattern;
    }
    
    if (FT_Error error = FT_New_Face(m_library, filename, id, &m_face)) {
    //if (FT_Error error = FT_New_Face(m_library, too, id, &m_face)) {
        DS_WAR("fail to open font" <<  filename << "with index " << id << " (error = 0x%x)\n" << error);
        m_face = 0;
        goto freePattern;
    }

    FT_Set_Pixel_Sizes(m_face, 0, static_cast<uint> (fontDescription.computedSize()));
    //DBGML(MODULE_FONTS, LEVEL_INFO, "open font %s with size %d\n", filename, static_cast<uint> (fontDescription.specifiedSize()));

freePattern:
    FcPatternDestroy(pattern);
    FcConfigDestroy(config);
}
void Java_org_iisc_mile_indictext_android_EditIndicText_drawIndicText(
		JNIEnv* env, jobject thiz, jstring unicodeText, jint xStart,
		jint yBaseLine, jint charHeight, jobject lock) {
	FT_Library ft_library;
	FT_Face ft_face;

	hb_font_t *font;
	hb_buffer_t *buffer;
	int glyph_count;
	hb_glyph_info_t *glyph_info;
	hb_glyph_position_t *glyph_pos;
	hb_bool_t fail;

	FT_UInt glyph_index;
	FT_GlyphSlot slot;
	FT_Error error;

	char* fontFilePath;
	jboolean iscopy;
	const jchar *text;
	int num_chars, i;

	int pen_x;
	int glyphPosX, glyphPosY;

	fontFilePath =
			"/sdcard/Android/data/org.iisc.mile.indictext.android/Lohit-Kannada.ttf";
	text = (*env)->GetStringChars(env, unicodeText, &iscopy);
	num_chars = (*env)->GetStringLength(env, unicodeText);

	error = FT_Init_FreeType(&ft_library); /* initialize library */
	if (error) {
		__android_log_print(6, "drawIndicText",
				"Error initializing FreeType library\n");
		return;
	}
	__android_log_print(2, "drawIndicText",
			"Successfully initialized FreeType library\n");

	error = FT_New_Face(ft_library, fontFilePath, 0, &ft_face); /* create face object */
	if (error == FT_Err_Unknown_File_Format) {
		__android_log_print(6, "drawIndicText",
				"The font file could be opened and read, but it appears that its font format is unsupported");
		return;
	} else if (error) {
		__android_log_print(6, "drawIndicText",
				"The font file could not be opened or read, or it might be broken");
		return;
	}
	__android_log_print(2, "drawIndicText",
			"Successfully created font-face object\n");

	font = hb_ft_font_create(ft_face, NULL);

	error = FT_Set_Pixel_Sizes(ft_face, 0, charHeight); /* set character size */
	/* error handling omitted */
	__android_log_print(2, "drawIndicText",
			"Successfully set character size to %d\n", charHeight);

	__android_log_print(2, "drawIndicText", "Text being rendered = %s\n", text);
	slot = ft_face->glyph;
	pen_x = xStart;

	/* Create a buffer for harfbuzz to use */
	buffer = hb_buffer_create();

	//hb_buffer_set_unicode_funcs(buffer, hb_icu_get_unicode_funcs());
	//alternatively you can use hb_buffer_set_unicode_funcs(buffer, hb_glib_get_unicode_funcs());

	//hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); /* or LTR */
	hb_buffer_set_script(buffer, HB_SCRIPT_KANNADA); /* see hb-unicode.h */
	//hb_buffer_set_language(buffer, hb_language_from_string("ka"));

	/* Layout the text */
	hb_buffer_add_utf16(buffer, text, num_chars, 0, num_chars);
	__android_log_print(2, "drawIndicText", "Before HarfBuzz shape()\n");
	hb_shape(font, buffer, NULL, 0);
	__android_log_print(2, "drawIndicText", "After HarfBuzz shape()\n");

	glyph_count = hb_buffer_get_length(buffer);
	glyph_info = hb_buffer_get_glyph_infos(buffer, 0);
	glyph_pos = hb_buffer_get_glyph_positions(buffer, 0);

	for (i = 0; i < glyph_count; i++) {
		glyph_index = glyph_info[i].codepoint;
		__android_log_print(2, "drawIndicText", "Glyph%d = %x", i, glyph_index);
		error = FT_Load_Glyph(ft_face, glyph_index, FT_LOAD_DEFAULT);
		if (error) {
			continue; /* ignore errors */
		}
		/* convert to an anti-aliased bitmap */
		error = FT_Render_Glyph(ft_face->glyph, FT_RENDER_MODE_NORMAL);
		if (error) {
			continue;
		}

		/* now, draw to our target surface (convert position) */
		draw_bitmap(&slot->bitmap, pen_x + slot->bitmap_left,
				yBaseLine - slot->bitmap_top, env, thiz, lock);
		//glyphPosX = pen_x + glyph_pos[i].x_offset;
		//glyphPosY = yBaseLine - glyph_pos[i].y_offset;
		//draw_bitmap(&slot->bitmap, glyphPosX, glyphPosY, env, thiz, lock);

		/* increment pen position */
		pen_x += slot->advance.x >> 6;
		//pen_x += glyph_pos[i].x_advance / 64;
		__android_log_print(2, "drawIndicText",
				"\tx_offset = %d\ty_offset = %d\tx_advance = %d\ty_advance = %d\n",
				glyph_pos[i].x_offset / 64, glyph_pos[i].y_offset / 64,
				glyph_pos[i].x_advance / 64, glyph_pos[i].y_advance / 64);
		__android_log_print(2, "drawIndicText",
				"\tbitmap_left = %d\tbitmap_top = %d\tadvance.x = %d\tadvance.y = %d\n",
				slot->bitmap_left, slot->bitmap_top, slot->advance.x >> 6,
				slot->advance.y >> 6);
	}

	hb_buffer_destroy(buffer);

	(*env)->ReleaseStringChars(env, unicodeText, text);
	hb_font_destroy(font);
	FT_Done_Face(ft_face);
	FT_Done_FreeType(ft_library);

	return;
}
Esempio n. 9
0
File: font.cpp Progetto: Zoxc/scaled
	bool Font::allocate(const char *name)
	{
		this->name = name;

		return FT_New_Face(library, name, 0, &face) == 0;
	}
Esempio n. 10
0
	bool Text2D::loadFont( std::map<GLchar, Character>& p_characters, const char *p_fontFile, const FT_UInt p_height ) {
		// FreeType
		FT_Library ft;

		// All functions return a value different than 0 whenever an error occurred
		if ( FT_Init_FreeType( &ft ) ) {
			wxLogMessage( wxT( "FreeType: Could not initialize FreeType library." ) );
			return false;
		}

		// Load font as face
		FT_Face face;
		if ( FT_New_Face( ft, p_fontFile, 0, &face ) ) {
			wxLogMessage( wxT( "FreeType: Failed to load font." ) );
			return false;
		}

		// Set size to load glyphs as
		FT_Set_Pixel_Sizes( face, 0, p_height );

		// Disable byte-alignment restriction
		glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );

		// Create 128 Charr charracters
		for ( unsigned char charr = 0; charr < 128; charr++ ) {
			// Load character glyph
			if ( FT_Load_Char( face, charr, FT_LOAD_RENDER ) ) {
				wxLogMessage( wxT( "FreeType: Failed to load Glyph." ) );
				continue;
			}

			// Generate texture
			GLuint texture;
			glGenTextures( 1, &texture );
			glBindTexture( GL_TEXTURE_2D, texture );
			glTexImage2D(
				GL_TEXTURE_2D,
				0,
				GL_RED,
				face->glyph->bitmap.width,
				face->glyph->bitmap.rows,
				0,
				GL_RED,
				GL_UNSIGNED_BYTE,
				face->glyph->bitmap.buffer
				);

			// Set texture options
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

			// Now store character for later use
			Character charracter = {
				texture,
				glm::ivec2( face->glyph->bitmap.width, face->glyph->bitmap.rows ),
				glm::ivec2( face->glyph->bitmap_left, face->glyph->bitmap_top ),
				static_cast<GLuint>( face->glyph->advance.x )
			};
			p_characters.insert( std::pair<GLchar, Character>( charr, charracter ) );
		}
		glBindTexture( GL_TEXTURE_2D, 0 );

		// Destroy FreeType once we're finished
		FT_Done_Face( face );
		FT_Done_FreeType( ft );

		return true;
	}
Esempio n. 11
0
/*-----------------------------------------------------------------------------------------------
Description:
    Governs window creation, the initial OpenGL configuration (face culling, depth mask, even
    though this is a 2D demo and that stuff won't be of concern), the creation of geometry, and
    the creation of a texture.
Parameters:
    argc    (From main(...)) The number of char * items in argv.  For glut's initialization.
    argv    (From main(...)) A collection of argument strings.  For glut's initialization.
Returns:
    False if something went wrong during initialization, otherwise true;
Exception:  Safe
Creator:
    John Cox (3-7-2016)
-----------------------------------------------------------------------------------------------*/
bool init(int argc, char *argv[])
{
    glutInit(&argc, argv);

    // I don't know what this is doing, but it has been working, so I'll leave it be for now
    int windowWidth = 500;  // square 500x500 pixels
    int windowHeight = 500;
    unsigned int displayMode = GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH | GLUT_STENCIL;
    displayMode = defaults(displayMode, windowWidth, windowHeight);
    glutInitDisplayMode(displayMode);

    // create the window
    // ??does this have to be done AFTER glutInitDisplayMode(...)??
    glutInitWindowSize(windowWidth, windowHeight);
    glutInitWindowPosition(300, 200);   // X = 0 is screen left, Y = 0 is screen top
    int window = glutCreateWindow(argv[0]);
    glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);

    // OpenGL 4.3 was where internal debugging was enabled, freeing the user from having to call
    // glGetError() and analyzing it after every single OpenGL call, complete with surrounding it
    // with #ifdef DEBUG ... #endif blocks
    // Note: https://blog.nobel-joergensen.com/2013/02/17/debugging-opengl-part-2-using-gldebugmessagecallback/
    int glMajorVersion = 4;
    int glMinorVersion = 4;
    glutInitContextVersion(glMajorVersion, glMinorVersion);
    glutInitContextProfile(GLUT_CORE_PROFILE);
#ifdef DEBUG
    glutInitContextFlags(GLUT_DEBUG);   // if enabled, 
#endif

    // glload must load AFTER glut loads the context
    glload::LoadTest glLoadGood = glload::LoadFunctions();
    if (!glLoadGood)    // apparently it has an overload for "bool type"
    {
        printf("glload::LoadFunctions() failed\n");
        return false;
    }
    else if (!glload::IsVersionGEQ(glMajorVersion, glMinorVersion))
    {
        // the "is version" check is an "is at least version" check
        printf("Your OpenGL version is %i, %i. You must have at least OpenGL %i.%i to run this tutorial.\n",
            glload::GetMajorVersion(), glload::GetMinorVersion(), glMajorVersion, glMinorVersion);
        glutDestroyWindow(window);
        return 0;
    }
    else if (glext_ARB_debug_output)
    {
        // condition will be true if GLUT_DEBUG is a context flag
        glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
        glDebugMessageCallbackARB(DebugFunc, (void*)15);
    }

    // these OpenGL initializations are for 3D stuff, where depth matters and multiple shapes can
    // be "on top" of each other relative to the most distant thing rendered, and this barebones 
    // code is only for 2D stuff, but initialize them anyway as good practice (??bad idea? only 
    // use these once 3D becomes a thing??)
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
    glFrontFace(GL_CCW);
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glDepthFunc(GL_LEQUAL);
    glDepthRange(0.0f, 1.0f);

    // FreeType needs to load itself into particular variables
    // Note: FT_Init_FreeType(...) returns something called an FT_Error, which VS can't find.
    // Based on the useage, it is assumed that 0 is returned if something went wrong, otherwise
    // non-zero is returned.  That is the only explanation for this kind of condition.
    if (FT_Init_FreeType(&gFtLib))
    {
        fprintf(stderr, "Could not init freetype library\n");
        return false;
    }
    
    // Note: FT_New_Face(...) also returns an FT_Error.
    const char *fontFilePath = "FreeSans.ttf";  // file path relative to solution directory
    if (FT_New_Face(gFtLib, fontFilePath, 0, &gFtFace))
    {
        fprintf(stderr, "Could not open font '%s'\n", fontFilePath);
        return false;
    }

    gProgramId = CreateProgram();
    
    // pick out the attributes and uniforms used in the FreeType GPU program

    char textTextureName[] = "textureSamplerId";
    gUniformTextSamplerLoc = glGetUniformLocation(gProgramId, textTextureName);
    if (gUniformTextSamplerLoc == -1)
    {
        fprintf(stderr, "Could not bind uniform '%s'\n", textTextureName);
        return false;
    }

    //char textColorName[] = "color";
    char textColorName[] = "textureColor";
    gUniformTextColorLoc = glGetUniformLocation(gProgramId, textColorName);
    if (gUniformTextColorLoc == -1)
    {
        fprintf(stderr, "Could not bind uniform '%s'\n", textColorName);
        return false;
    }

    // start up the font texture atlas now that the program is created and uniforms are recorded
    gAtlasPtr = new atlas(gFtFace, 48);

    // create the vertex buffer that will be used to create quads as a base for the FreeType 
    // glyph textures
    glGenBuffers(1, &gVbo);
    if (gVbo == -1)
    {
        fprintf(stderr, "could not generate vertex buffer object\n");
        return false;
    }

    // all went well
    return true;
}
static FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
{
	FT_Error err = FT_Err_Cannot_Open_Resource;
	HKEY hKey;
	LONG ret;
	TCHAR vbuffer[MAX_PATH], dbuffer[256];
	TCHAR *font_namep;
	char *font_path;
	uint index;

	/* On windows NT (2000, NT3.5, XP, etc.) the fonts are stored in the
	 * "Windows NT" key, on Windows 9x in the Windows key. To save us having
	 * to retrieve the windows version, we'll just query both */
	ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T(FONT_DIR_NT), 0, KEY_READ, &hKey);
	if (ret != ERROR_SUCCESS) ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T(FONT_DIR_9X), 0, KEY_READ, &hKey);

	if (ret != ERROR_SUCCESS) {
		DEBUG(freetype, 0, "Cannot open registry key HKLM\\SOFTWARE\\Microsoft\\Windows (NT)\\CurrentVersion\\Fonts");
		return err;
	}

	/* For Unicode we need some conversion between widechar and
	 * normal char to match the data returned by RegEnumValue,
	 * otherwise just use parameter */
#if defined(UNICODE)
	font_namep = MallocT<TCHAR>(MAX_PATH);
	MB_TO_WIDE_BUFFER(font_name, font_namep, MAX_PATH * sizeof(TCHAR));
#else
	font_namep = const_cast<char *>(font_name); // only cast because in unicode pointer is not const
#endif

	for (index = 0;; index++) {
		TCHAR *s;
		DWORD vbuflen = lengthof(vbuffer);
		DWORD dbuflen = lengthof(dbuffer);

		ret = RegEnumValue(hKey, index, vbuffer, &vbuflen, NULL, NULL, (byte*)dbuffer, &dbuflen);
		if (ret != ERROR_SUCCESS) goto registry_no_font_found;

		/* The font names in the registry are of the following 3 forms:
		 * - ADMUI3.fon
		 * - Book Antiqua Bold (TrueType)
		 * - Batang & BatangChe & Gungsuh & GungsuhChe (TrueType)
		 * We will strip the font-type '()' if any and work with the font name
		 * itself, which must match exactly; if...
		 * TTC files, font files which contain more than one font are seperated
		 * byt '&'. Our best bet will be to do substr match for the fontname
		 * and then let FreeType figure out which index to load */
		s = _tcschr(vbuffer, _T('('));
		if (s != NULL) s[-1] = '\0';

		if (_tcschr(vbuffer, _T('&')) == NULL) {
			if (_tcsicmp(vbuffer, font_namep) == 0) break;
		} else {
			if (_tcsstr(vbuffer, font_namep) != NULL) break;
		}
	}

	if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, vbuffer))) {
		DEBUG(freetype, 0, "SHGetFolderPath cannot return fonts directory");
		goto folder_error;
	}

	/* Some fonts are contained in .ttc files, TrueType Collection fonts. These
	 * contain multiple fonts inside this single file. GetFontData however
	 * returns the whole file, so we need to check each font inside to get the
	 * proper font.
	 * Also note that FreeType does not support UNICODE filesnames! */
#if defined(UNICODE)
	/* We need a cast here back from wide because FreeType doesn't support
	 * widechar filenames. Just use the buffer we allocated before for the
	 * font_name search */
	font_path = (char*)font_namep;
	WIDE_TO_MB_BUFFER(vbuffer, font_path, MAX_PATH * sizeof(TCHAR));
#else
	font_path = vbuffer;
#endif

	ttd_strlcat(font_path, "\\", MAX_PATH * sizeof(TCHAR));
	ttd_strlcat(font_path, WIDE_TO_MB(dbuffer), MAX_PATH * sizeof(TCHAR));

	/* Convert the path into something that FreeType understands */
	font_path = GetShortPath(font_path);

	index = 0;
	do {
		err = FT_New_Face(_library, font_path, index, face);
		if (err != FT_Err_Ok) break;

		if (strncasecmp(font_name, (*face)->family_name, strlen((*face)->family_name)) == 0) break;
		/* Try english name if font name failed */
		if (strncasecmp(font_name + strlen(font_name) + 1, (*face)->family_name, strlen((*face)->family_name)) == 0) break;
		err = FT_Err_Cannot_Open_Resource;

	} while ((FT_Long)++index != (*face)->num_faces);


folder_error:
registry_no_font_found:
#if defined(UNICODE)
	free(font_namep);
#endif
	RegCloseKey(hKey);
	return err;
}
/* ========================================================================================
 * FontConfig (unix) support
 * ======================================================================================== */
static FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
{
	FT_Error err = FT_Err_Cannot_Open_Resource;

	if (!FcInit()) {
		ShowInfoF("Unable to load font configuration");
	} else {
		FcPattern *match;
		FcPattern *pat;
		FcFontSet *fs;
		FcResult  result;
		char *font_style;
		char *font_family;

		/* Split & strip the font's style */
		font_family = strdup(font_name);
		font_style = strchr(font_family, ',');
		if (font_style != NULL) {
			font_style[0] = '\0';
			font_style++;
			while (*font_style == ' ' || *font_style == '\t') font_style++;
		}

		/* Resolve the name and populate the information structure */
		pat = FcNameParse((FcChar8*)font_family);
		if (font_style != NULL) FcPatternAddString(pat, FC_STYLE, (FcChar8*)font_style);
		FcConfigSubstitute(0, pat, FcMatchPattern);
		FcDefaultSubstitute(pat);
		fs = FcFontSetCreate();
		match = FcFontMatch(0, pat, &result);

		if (fs != NULL && match != NULL) {
			int i;
			FcChar8 *family;
			FcChar8 *style;
			FcChar8 *file;
			FcFontSetAdd(fs, match);

			for (i = 0; err != FT_Err_Ok && i < fs->nfont; i++) {
				/* Try the new filename */
				if (FcPatternGetString(fs->fonts[i], FC_FILE,   0, &file)   == FcResultMatch &&
						FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, &family) == FcResultMatch &&
						FcPatternGetString(fs->fonts[i], FC_STYLE,  0, &style)  == FcResultMatch) {

					/* The correct style? */
					if (font_style != NULL && strcasecmp(font_style, (char*)style) != 0) continue;

					/* Font config takes the best shot, which, if the family name is spelled
					 * wrongly a 'random' font, so check whether the family name is the
					 * same as the supplied name */
					if (strcasecmp(font_family, (char*)family) == 0) {
						err = FT_New_Face(_library, (char *)file, 0, face);
					}
				}
			}
		}

		free(font_family);
		FcPatternDestroy(pat);
		FcFontSetDestroy(fs);
		FcFini();
	}

	return err;
}
Esempio n. 14
0
HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, int lfWeight, char lfItalic, 
  char lfUnderline, char lfStrikeOut, char lfCharSet, char lfOutPrecision, char lfClipPrecision, 
         char lfQuality, char lfPitchAndFamily, const char *lfFaceName)
{
  HGDIOBJ__ *font=NULL;
#ifdef SWELL_FREETYPE
  FT_Face face=NULL;
  if (!s_freetype_failed && !s_freetype) s_freetype_failed = !!FT_Init_FreeType(&s_freetype);
  if (s_freetype)
  {
    if (!lfFaceName || !*lfFaceName) lfFaceName = "Arial";

    int fn_len = strlen(lfFaceName);

    const char *leadpath = "/usr/share/fonts/truetype/msttcorefonts"; // todo: scan subdirs?
    char tmp[1024];
    char bestmatch[512];
    bestmatch[0]=0;
    int x;
    for (x=0;x < s_registered_fonts.GetSize(); x ++)
    {
      const char *fn = s_registered_fonts.Get(x);
      if (fn)
      {
        const char *fnpart = WDL_get_filepart(fn);
        if (!strnicmp(fnpart,lfFaceName,strlen(lfFaceName)))
        {
          FT_New_Face(s_freetype,fn,0,&face);
          if (face) break;
        }
      }
    }

    if (!face)
    {
      snprintf(tmp,sizeof(tmp),"%s/%s.ttf",leadpath,lfFaceName);
      FT_New_Face(s_freetype,tmp,0,&face);
    }
    if (!face)
    {
      WDL_DirScan ds;
      if (!ds.First(leadpath)) do
      { 
        if (!strnicmp(ds.GetCurrentFN(),lfFaceName,fn_len))
        {
          if (!stricmp(ds.GetCurrentFN()+fn_len,".ttf"))
          {
            snprintf(tmp,sizeof(tmp),"%s/%s",leadpath,ds.GetCurrentFN());
            FT_New_Face(s_freetype,tmp,0,&face);
          }
          else 
          {
            // todo look for italic/bold/etc too
            int sl = strlen(ds.GetCurrentFN());
            if (sl > 4 && !stricmp(ds.GetCurrentFN() + sl - 4, ".ttf")  && (!bestmatch[0] || sl < strlen(bestmatch)))
            {
              lstrcpyn_safe(bestmatch,ds.GetCurrentFN(),sizeof(bestmatch));
            }
          }
        }
      } while (!face && !ds.Next());
      if (!face && bestmatch[0])
      {
        snprintf(tmp,sizeof(tmp),"%s/%s",leadpath,bestmatch);
        FT_New_Face(s_freetype,tmp,0,&face);
      }
    }
    if (!face) FT_New_Face(s_freetype,"/usr/share/fonts/truetype/freefont/FreeSans.ttf",0,&face);
    if (!face) FT_New_Face(s_freetype,"/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf",0,&face);
  }
  
  if (face)
  {
    font = GDP_OBJECT_NEW();
    font->type=TYPE_FONT;
    font->fontface = face;
    font->alpha = 1.0f;
    ////unsure here
    if (lfWidth<0) lfWidth=-lfWidth;
    if (lfHeight<0) lfHeight=-lfHeight;
    FT_Set_Char_Size(face,lfWidth*64, lfHeight*64,0,0); // 72dpi
//    FT_Set_Pixel_Sizes(face,0,lfHeight);
  }
#else
  font->type=TYPE_FONT;
#endif
 
  return font;
}
Esempio n. 15
0
	void InstalledFontList::Load()
	{
		if (isLoaded) return;
		isLoaded = true;

		std::vector<std::string> paths;
#ifdef _WIN32
		EnumerateFiles("C:\\Windows\\Fonts\\", paths);
#elif defined __APPLE__
		EnumerateFiles("/System/Library/Fonts/", paths);
		EnumerateFiles("/Library/Fonts/", paths);
#endif

		FT_Library library = nullptr;
		auto error = FT_Init_FreeType(&library);

		for (auto& path : paths)
		{
			auto ext_ = GetFileExt(path.c_str());
			std::string ext(ext_);
			std::transform(ext_.begin(), ext_.end(), ext.begin(), tolower_);

			// fonはアウトラインでないので未対応
			if (ext == std::string("fon"))
			{
				continue;
			}

			FT_Face face = nullptr;
			FT_New_Face(library, path.c_str(), 0, &face);
			if (face == nullptr) continue;

			Font font;
			font.Name = ToAString(face->family_name);
			font.Path = ToAString(path.c_str());

			Fonts.push_back(font);

			FT_Done_Face(face);
		}

		FT_Done_FreeType(library);

		// レジストリだとフルネームが長い
		/*
		HKEY fontKey;

		// レジストリを開く
		auto r = RegOpenKeyExA(
			HKEY_LOCAL_MACHINE,
			"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts",
			0,
			KEY_READ,
			&fontKey);

		if (r != ERROR_SUCCESS) return;

		for (auto ind = 0;; ind++)
		{
			char valueName[1000];
			DWORD valueNameSize = 1000;

			char value[1000];
			DWORD valueSize = 1000;

			DWORD valueType;

			auto result = SHEnumValueA(
				fontKey,
				ind,
				valueName,
				&valueNameSize,
				&valueType,
				value,
				&valueSize);

			if (result != ERROR_SUCCESS) break;

			Font font;
			font.Name = ToAString(valueName);
			font.Path = ToAString(value);

			Fonts.push_back(font);
		}

		// 終了
		RegCloseKey(fontKey);
		*/
	}
Esempio n. 16
0
//------------------------------------------------------------------
void urFont::loadFont(string filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet, bool makeContours){
	
	
	
	bMakeContours = makeContours;

	//------------------------------------------------
	if (bLoadedOk == true){

		// we've already been loaded, try to clean up :

		if (cps != NULL){
			delete[] cps;
		}
		if (texNames != NULL){
			for (int i = 0; i < nCharacters; i++){
				glDeleteTextures(1, &texNames[i]);
			}
			delete[] texNames;
		}
		bLoadedOk = false;
	}
	//------------------------------------------------


	filename = ofToDataPath(filename);

	bLoadedOk 			= false;
	bAntiAlised 		= _bAntiAliased;
	bFullCharacterSet 	= _bFullCharacterSet;
	fontSize			= fontsize;

	//--------------- load the library and typeface
	FT_Library library;
	if (FT_Init_FreeType( &library )){
		//		ofLog(OF_LOG_ERROR," PROBLEM WITH FT lib");
		return;
	}

	FT_Face face;
	if (FT_New_Face( library, filename.c_str(), 0, &face )) {
		return;
	}

	FT_Set_Char_Size( face, fontsize << 6, fontsize << 6, 96, 96);
	lineHeight = fontsize * 1.43f;

	//------------------------------------------------------
	//kerning would be great to support:
	//ofLog(OF_LOG_NOTICE,"FT_HAS_KERNING ? %i", FT_HAS_KERNING(face));
	//------------------------------------------------------

	nCharacters = bFullCharacterSet ? 256 : 128 - NUM_CHARACTER_TO_START;

	//--------------- initialize character info and textures
	cps       = new charProps[nCharacters];
	texNames  = new GLuint[nCharacters];
	glGenTextures(nCharacters, texNames);

	if(bMakeContours){
		charOutlines.clear();
		charOutlines.assign(nCharacters, ofTTFCharacter());
	}
	//--------------------- load each char -----------------------
	for (int i = 0 ; i < nCharacters; i++){

		//------------------------------------------ anti aliased or not:
		if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){
			//			ofLog(OF_LOG_ERROR,"error with FT_Load_Glyph %i", i);
		}

		if (bAntiAlised == true) FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
		else FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO);

		//------------------------------------------
		FT_Bitmap& bitmap= face->glyph->bitmap;

		// 3 pixel border around the glyph
		// We show 2 pixels of this, so that blending looks good.
		// 1 pixels is hidden because we don't want to see the real edge of the texture

		border			= 3;
		visibleBorder	= 2;

		if(bMakeContours){
			if( printVectorInfo )printf("\n\ncharacter %c: \n", char( i+NUM_CHARACTER_TO_START ) );

			//int character = i + NUM_CHARACTER_TO_START;
			charOutlines[i] = makeContoursForCharacter( face );
		}

		// prepare the texture:
		int width  = ofNextPow2( bitmap.width + border*2 );
		int height = ofNextPow2( bitmap.rows  + border*2 );


		// ------------------------- this is fixing a bug with small type
		// ------------------------- appearantly, opengl has trouble with
		// ------------------------- width or height textures of 1, so we
		// ------------------------- we just set it to 2...
		if (width == 1) width = 2;
		if (height == 1) height = 2;

		// -------------------------
		// info about the character:
		cps[i].value 			= i;
		cps[i].height 			= face->glyph->bitmap_top;
		cps[i].width 			= face->glyph->bitmap.width;
		cps[i].setWidth 		= face->glyph->advance.x >> 6;
		cps[i].topExtent 		= face->glyph->bitmap.rows;
		cps[i].leftExtent		= face->glyph->bitmap_left;

		// texture internals
		cps[i].tTex             = (float)(bitmap.width + visibleBorder*2)  /  (float)width;
		cps[i].vTex             = (float)(bitmap.rows +  visibleBorder*2)   /  (float)height;

		cps[i].xOff             = (float)(border - visibleBorder) / (float)width;
		cps[i].yOff             = (float)(border - visibleBorder) / (float)height;


		/* sanity check:
		ofLog(OF_LOG_NOTICE,"%i %i %i %i %i %i",
		cps[i].value ,
		cps[i].height ,
		cps[i].width 	,
		cps[i].setWidth 	,
		cps[i].topExtent ,
		cps[i].leftExtent	);
		*/


		// Allocate Memory For The Texture Data.
		unsigned char* expanded_data = new unsigned char[ 2 * width * height];

		//-------------------------------- clear data:
		for(int j=0; j <height;j++) {
			for(int k=0; k < width; k++){
				expanded_data[2*(k+j*width)  ] = 255;   // every luminance pixel = 255
				expanded_data[2*(k+j*width)+1] = 0;
			}
		}


		if (bAntiAlised == true){
			//-----------------------------------
			for(int j=0; j <height; j++) {
				for(int k=0; k < width; k++){
					if ((k<bitmap.width) && (j<bitmap.rows)){
						expanded_data[2*((k+border)+(j+border)*width)+1] = bitmap.buffer[k + bitmap.width*(j)];
					}
				}
			}
			//-----------------------------------
		} else {
			//-----------------------------------
			// true type packs monochrome info in a
			// 1-bit format, hella funky
			// here we unpack it:
			unsigned char *src =  bitmap.buffer;
			for(int j=0; j <bitmap.rows;j++) {
				unsigned char b=0;
				unsigned char *bptr =  src;
				for(int k=0; k < bitmap.width ; k++){
					expanded_data[2*((k+1)+(j+1)*width)] = 255;
					if (k%8==0){ b = (*bptr++);}
					expanded_data[2*((k+1)+(j+1)*width) + 1] =
						b&0x80 ? 255 : 0;
					b <<= 1;
				}
				src += bitmap.pitch;
			}
			//-----------------------------------
		}


		//Now we just setup some texture paramaters.
		glBindTexture( GL_TEXTURE_2D, texNames[i]);
#if (!defined TARGET_OF_IPHONE) && (!defined TARGET_ANDROID)
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
#endif
		if (bAntiAlised == true){
			glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
			glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		} else {
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
		}
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

		//Here we actually create the texture itself, notice
		//that we are using GL_LUMINANCE_ALPHA to indicate that
		//we are using 2 channel data.

#if (!defined TARGET_OF_IPHONE) && (!defined TARGET_ANDROID) // gluBuild2DMipmaps doesn't seem to exist in anything i had in the iphone build... so i commented it out
		bool b_use_mipmaps = false;  // FOR now this is fixed to false, could be an option, left in for legacy...
		if (b_use_mipmaps){
			gluBuild2DMipmaps(
				GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, width, height,
				GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data);
		} else
#endif
		{
			glTexImage2D( GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, width, height,
				0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data );
		}


		//With the texture created, we don't need to expanded data anymore

		delete [] expanded_data;

	}

	// ------------- close the library and typeface
	FT_Done_Face(face);
	FT_Done_FreeType(library);
	bLoadedOk = true;
}
    int PsychRebuildFont(void)
    {
        // Destroy old font object, if any:
        if (faceT || faceM) {
            // Delete OGLFT face object:
            if (faceT) delete(faceT);
            faceT = NULL;

            if (faceM) delete(faceM);
            faceM = NULL;

            if (_verbosity > 3) fprintf(stderr, "libptbdrawtext_ftgl: Destroying old font face...\n");

            // Delete underlying FreeType representation:
            FT_Done_Face(ft_face);
            ft_face = NULL;
        }

        if (_useOwnFontmapper) {
            FcResult result = FcResultMatch; // Must init this due to weirdness in libfontconfig...
            FcPattern* target = NULL;

            if (_fontName[0] == '-') {
                // _fontName starts with a '-' dash: This is not a simple font family string but a special
                // fontspec string in FontConfig's special format. It contains many possible required font
                // properties encoded in the string. Parse it into a font matching pattern:
                target = FcNameParse((FcChar8*) &(_fontName[1]));

                // Need to manually add the current _fontSize, otherwise inconsistent stuff may happen:
                FcPatternAddDouble(target, FC_PIXEL_SIZE, _fontSize);
            }
            else {
                // _fontName contains only font family name: Build matching pattern based on _fontSize and
                // the flags provided in _fontStyle, according to the conventions in Psychtoolbox Screen('TextStyle'):
                target = FcPatternBuild (0, FC_FAMILY, FcTypeString, _fontName, FC_PIXEL_SIZE, FcTypeDouble, _fontSize,
                                         FC_WEIGHT, FcTypeInteger, ((_fontStyle & 1) ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL),
                                         FC_SLANT, FcTypeInteger, ((_fontStyle & 2) ?  FC_SLANT_ITALIC : FC_SLANT_ROMAN),
                                         FC_OUTLINE, FcTypeBool, ((_fontStyle & 8) ? true : false),
                                         FC_WIDTH, FcTypeInteger, ( (_fontStyle & 32) ?  FC_WIDTH_CONDENSED : ((_fontStyle & 64) ?  FC_WIDTH_EXPANDED : FC_WIDTH_NORMAL) ),
                                         FC_DPI, FcTypeDouble, (double) 72.0,
                                         FC_SCALABLE, FcTypeBool, true,
                                         FC_ANTIALIAS, FcTypeBool, ((_antiAliasing != 0) ? true : false),
                                         NULL);
            }

            // Set default settings for missing pattern properties:
            FcDefaultSubstitute(target);
            if (!FcConfigSubstitute(NULL, target, FcMatchPattern)) {
                // Failed!
                if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: FontConfig failed to substitute default properties for family %s, size %f pts and style flags %i.\n", _fontName, (float) _fontSize, _fontStyle);
                FcPatternDestroy(target);
                return(1);
            }

            // Have a matching pattern:
            if (_verbosity > 3) {
                fprintf(stderr, "libptbdrawtext_ftgl: Trying to find font that closely matches following specification:\n");
                FcPatternPrint(target);
            }

            // Perform font matching for the font in the default configuration (0) that best matches the
            // specified target pattern:
            FcPattern* matched = FcFontMatch(NULL, target, &result);
            if ((matched == NULL) || (result == FcResultNoMatch)) {
                // Failed!
                if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: FontConfig failed to find a matching font for family %s, size %f pts and style flags %i.\n", _fontName, (float) _fontSize, _fontStyle);
                FcPatternDestroy(target);
                return(1);
            }

            // Success: Extract relevant information for Freetype-2, the font filename and faceIndex:
            if (_verbosity > 3) {
                fprintf(stderr, "libptbdrawtext_ftgl: Best matching font which will be selected for drawing has following specs:\n");
                FcPatternPrint(matched);
            }

            // Retrieve font filename for matched font:
            FcChar8* localfontFileName = NULL;
            if (FcPatternGetString(matched, FC_FILE, 0, (FcChar8**) &localfontFileName) != FcResultMatch) {
                // Failed!
                if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: FontConfig did not find filename for font with family %s, size %f pts and style flags %i.\n", _fontName, (float) _fontSize, _fontStyle);
                FcPatternDestroy(target);
                FcPatternDestroy(matched);
                return(1);
            }

            strcpy(_fontFileName, (char*) localfontFileName);

            // Retrieve faceIndex within fontfile:
            if (FcPatternGetInteger(matched, FC_INDEX, 0, &_faceIndex) != FcResultMatch)  {
                // Failed!
                if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: FontConfig did not find faceIndex for font file %s, family %s, size %f pts and style flags %i.\n", _fontFileName, _fontName, (float) _fontSize, _fontStyle);
                FcPatternDestroy(target);
                FcPatternDestroy(matched);
                return(1);
            }

            // Release target pattern and matched pattern objects:
            FcPatternDestroy(target);
            FcPatternDestroy(matched);
        }
        else {
            // Use "raw" values as passed by calling client code:
            strcpy(_fontFileName, _fontName);
            _faceIndex = (int) _fontStyle;
        }

        // Load & Create new font and face object, based on current spec settings:
        // We directly use the Freetype library, so we can spec the faceIndex for selection of textstyle, which wouldn't be
        // possible with the higher-level OGLFT constructor...
        FT_Error error = FT_New_Face( OGLFT::Library::instance(), _fontFileName, _faceIndex, &ft_face );
        if (error) {
            if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: Freetype did not load face with index %i from font file %s.\n", _faceIndex, _fontFileName);
            return(1);
        }
        else {
            if (_verbosity > 3) fprintf(stderr, "libptbdrawtext_ftgl: Freetype loaded face %p with index %i from font file %s.\n", ft_face, _faceIndex, _fontFileName);
        }

        // Create FTGL face from Freetype face with given size and a 72 DPI resolution, aka _fontSize == pixelsize:
        if (_antiAliasing != 0) {
            faceT = new OGLFT::TranslucentTexture(ft_face, _fontSize, 72);
            // Test the created face to make sure it will work correctly:
            if (!faceT->isValid()) {
                if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: Freetype did not recognize %s as a font file.\n", _fontName);
                return(1);
            }
        }
        else {
            faceM = new OGLFT::MonochromeTexture(ft_face, _fontSize, 72);
            // Test the created face to make sure it will work correctly:
            if (!faceM->isValid()) {
                if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: Freetype did not recognize %s as a font file.\n", _fontName);
                return(1);
            }
        }

        // Ready!
        _needsRebuild = false;

        return(0);
    }
// ------------------------------------------------------------- load_glyph ---
texture_glyph_t *
load_glyph( const char *  filename,     const wchar_t charcode,
            const float   highres_size, const float   lowres_size,
            const float   padding )
{
    size_t i, j;
    FT_Library library;
    FT_Face face;

    FT_Init_FreeType( &library );
    FT_New_Face( library, filename, 0, &face );
    FT_Select_Charmap( face, FT_ENCODING_UNICODE );
    FT_UInt glyph_index = FT_Get_Char_Index( face, charcode );

    // Render glyph at high resolution (highres_size points)
    FT_Set_Char_Size( face, highres_size*64, 0, 72, 72 );
    FT_Load_Glyph( face, glyph_index,
                   FT_LOAD_RENDER | FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT);
    FT_GlyphSlot slot = face->glyph;
    FT_Bitmap bitmap = slot->bitmap;

    // Allocate high resolution buffer
    size_t highres_width  = bitmap.width + 2*padding*highres_size;
    size_t highres_height = bitmap.rows + 2*padding*highres_size;
    double * highres_data = (double *) malloc( highres_width*highres_height*sizeof(double) );
    memset( highres_data, 0, highres_width*highres_height*sizeof(double) );

    // Copy high resolution bitmap with padding and normalize values
    for( j=0; j < bitmap.rows; ++j )
    {
        for( i=0; i < bitmap.width; ++i )
        {
            int x = i + padding;
            int y = j + padding;
            highres_data[y*highres_width+x] = bitmap.buffer[j*bitmap.width+i]/255.0;
        }
    }

    // Compute distance map
    distance_map( highres_data, highres_width, highres_height );

    // Allocate low resolution buffer
    size_t lowres_width  = round(highres_width * lowres_size/highres_size);
    size_t lowres_height = round(highres_height * lowres_width/(float) highres_width);
    double * lowres_data = (double *) malloc( lowres_width*lowres_height*sizeof(double) );
    memset( lowres_data, 0, lowres_width*lowres_height*sizeof(double) );

    // Scale down highres buffer into lowres buffer
    resize( highres_data, highres_width, highres_height,
            lowres_data,  lowres_width,  lowres_height );

    // Convert the (double *) lowres buffer into a (unsigned char *) buffer and
    // rescale values between 0 and 255.
    unsigned char * data =
        (unsigned char *) malloc( lowres_width*lowres_height*sizeof(unsigned char) );
    for( j=0; j < lowres_height; ++j )
    {
        for( i=0; i < lowres_width; ++i )
        {
            double v = lowres_data[j*lowres_width+i];
            data[j*lowres_width+i] = (int) (255*(1-v));
        }
    }

    // Compute new glyph information from highres value
    float ratio = lowres_size / highres_size;
    size_t pitch  = lowres_width * sizeof( unsigned char );

    // Create glyph
    texture_glyph_t * glyph = texture_glyph_new( );
    glyph->offset_x = (slot->bitmap_left + padding*highres_width) * ratio;
    glyph->offset_y = (slot->bitmap_top + padding*highres_height) * ratio;
    glyph->width    = lowres_width;
    glyph->height   = lowres_height;
    glyph->charcode = charcode;
    /*
    printf( "Glyph width:  %ld\n", glyph->width );
    printf( "Glyph height: %ld\n", glyph->height );
    printf( "Glyph offset x: %d\n", glyph->offset_x );
    printf( "Glyph offset y: %d\n", glyph->offset_y );
    */
    ivec4 region = texture_atlas_get_region( atlas, glyph->width, glyph->height );
    /*
    printf( "Region x : %d\n", region.x );
    printf( "Region y : %d\n", region.y );
    printf( "Region width : %d\n", region.width );
    printf( "Region height : %d\n", region.height );
    */
    texture_atlas_set_region( atlas, region.x, region.y, glyph->width, glyph->height, data, pitch );
    glyph->s0       = region.x/(float)atlas->width;
    glyph->t0       = region.y/(float)atlas->height;
    glyph->s1       = (region.x + glyph->width)/(float)atlas->width;
    glyph->t1       = (region.y + glyph->height)/(float)atlas->height;

    FT_Load_Glyph( face, glyph_index,
                   FT_LOAD_RENDER | FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT);
    glyph->advance_x = ratio * face->glyph->advance.x/64.0;
    glyph->advance_y = ratio * face->glyph->advance.y/64.0;
    /*
    printf( "Advance x : %f\n", glyph->advance_x );
    printf( "Advance y : %f\n", glyph->advance_y );
    */
    free( highres_data );
    free( lowres_data );
    free( data );

    return glyph;
}
Esempio n. 19
0
static GF_Err ft_set_font(GF_FontReader *dr, const char *OrigFontName, u32 styles)
{
    char *fname;
    char *fontName;
    const char *opt;
    FTBuilder *ftpriv = (FTBuilder *)dr->udta;

    fontName = (char *) OrigFontName;
    ftpriv->active_face = NULL;

    if (!fontName || !strlen(fontName) || !stricmp(fontName, "SERIF")) {
        fontName = ftpriv->font_serif;
    }
    else if (!stricmp(fontName, "SANS") || !stricmp(fontName, "sans-serif")) {
        fontName = ftpriv->font_sans;
    }
    else if (!stricmp(fontName, "TYPEWRITER") || !stricmp(fontName, "monospace")) {
        fontName = ftpriv->font_fixed;
    }

    /*first look in loaded fonts*/
    ftpriv->active_face = ft_font_in_cache(ftpriv, fontName, styles);
    if (ftpriv->active_face) return GF_OK;

    /*check cfg file - gf_free(type is slow at loading fonts so we keep the (font name + styles)=fontfile associations
    in the cfg file*/
    if (!fontName || !strlen(fontName)) return GF_NOT_SUPPORTED;
    fname = gf_malloc(sizeof(char) * (strlen(fontName) + 50));

    {
        int checkStyles = (styles & GF_FONT_WEIGHT_BOLD) | (styles & GF_FONT_ITALIC);
checkFont:
        strcpy(fname, fontName);
        if (styles & GF_FONT_WEIGHT_BOLD & checkStyles) strcat(fname, " Bold");
        if (styles & GF_FONT_ITALIC & checkStyles) strcat(fname, " Italic");

        opt = gf_modules_get_option((GF_BaseInterface *)dr, "FontEngine", fname);

        if (opt) {
            FT_Face face;
            gf_free(fname);
            if (FT_New_Face(ftpriv->library, opt, 0, & face )) return GF_IO_ERR;
            if (!face) return GF_IO_ERR;
            gf_list_add(ftpriv->loaded_fonts, face);
            ftpriv->active_face = face;
            return GF_OK;
        }
        if (checkStyles) {
            /* If we tried font + bold + italic -> we will try font + [bold | italic]
               If we tried font + [bold | italic] -> we try font
                 */
            if (checkStyles == (GF_FONT_WEIGHT_BOLD | GF_FONT_ITALIC))
                checkStyles = GF_FONT_WEIGHT_BOLD;
            else if (checkStyles == GF_FONT_WEIGHT_BOLD && (styles & GF_FONT_ITALIC))
                checkStyles = GF_FONT_ITALIC;
            else if (checkStyles == GF_FONT_WEIGHT_BOLD || checkStyles == GF_FONT_ITALIC)
                checkStyles = 0;
            goto checkFont;
        }
    }

    GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[FreeType] Font '%s' (%s) not found\n", fontName, fname));
    gf_free(fname);
    return GF_NOT_SUPPORTED;
}
Esempio n. 20
0
/**
 * \brief Select a face with the given charcode and add it to ASS_Font
 * \return index of the new face in font->faces, -1 if failed
 */
static int add_face(ASS_FontSelector *fontsel, ASS_Font *font, uint32_t ch)
{
    char *path;
    char *postscript_name = NULL;
    int i, index, uid, error;
    ASS_FontStream stream = { NULL, NULL };
    FT_Face face;

    if (font->n_faces == ASS_FONT_MAX_FACES)
        return -1;

    path = ass_font_select(fontsel, font->library, font , &index,
            &postscript_name, &uid, &stream, ch);

    if (!path)
        return -1;

    for (i = 0; i < font->n_faces; i++) {
        if (font->faces_uid[i] == uid) {
            ass_msg(font->library, MSGL_INFO,
                    "Got a font face that already is available! Skipping.");
            return i;
        }
    }

    if (stream.func) {
        FT_Open_Args args;
        FT_Stream ftstream = calloc(1, sizeof(FT_StreamRec));
        ASS_FontStream *fs  = calloc(1, sizeof(ASS_FontStream));

        *fs = stream;
        ftstream->size  = stream.func(stream.priv, NULL, 0, 0);
        ftstream->read  = read_stream_font;
        ftstream->close = close_stream_font;
        ftstream->descriptor.pointer = (void *)fs;

        memset(&args, 0, sizeof(FT_Open_Args));
        args.flags  = FT_OPEN_STREAM;
        args.stream = ftstream;

        error = FT_Open_Face(font->ftlibrary, &args, index, &face);

        if (error) {
            ass_msg(font->library, MSGL_WARN,
                    "Error opening memory font: '%s'", path);
            return -1;
        }

    } else {
        error = FT_New_Face(font->ftlibrary, path, index, &face);
        if (error) {
            ass_msg(font->library, MSGL_WARN,
                    "Error opening font: '%s', %d", path, index);
            return -1;
        }

        if (postscript_name && index < 0 && face->num_faces > 0) {
            // The font provider gave us a post_script name and is not sure
            // about the face index.. so use the postscript name to find the
            // correct face_index in the collection!
            for (int i = 0; i < face->num_faces; i++) {
                FT_Done_Face(face);
                error = FT_New_Face(font->ftlibrary, path, i, &face);
                if (error) {
                    ass_msg(font->library, MSGL_WARN,
                            "Error opening font: '%s', %d", path, i);
                    return -1;
                }

                const char *face_psname = FT_Get_Postscript_Name(face);
                if (face_psname != NULL &&
                    strcmp(face_psname, postscript_name) == 0)
                    break;
            }
        }
    }

    charmap_magic(font->library, face);
    buggy_font_workaround(face);

    font->faces[font->n_faces] = face;
    font->faces_uid[font->n_faces++] = uid;
    ass_face_set_size(face, font->size);
    return font->n_faces - 1;
}
Esempio n. 21
0
    bool FTFontAsset::GenerateFontStrip( pei::FontPtr font )
    {
    	bool font_ok(false);
        pei::FontManager fnt_manager;
        pei::FontManager::FontPathIterator fit     = fnt_manager.GetFontPathBegin();
        pei::FontManager::FontPathIterator fit_end = fnt_manager.GetFontPathEnd();
        while (!font_ok && fit != fit_end ) {
            bfs::path full_file_name = fit++->second / GetResourceName();
            bool fontExists = bfs::exists( full_file_name );
            bool hasExtension = full_file_name.extension() == GetFormatString();
            if ( hasExtension && fontExists )
            {
                bool noGlobalLibrary(s_FtLibrary == NULL);
                // not thread safe! Might have been initialized by FtFontFactory
                if ( noGlobalLibrary ) {
                    FT_Error error = FT_Init_FreeType( &s_FtLibrary );
                    if ( error ) {
                        std::cerr << "Error loading Freetype library\n" << std::endl;
                        return false;
                    }
                }
                FT_Face face;
                if (FT_New_Face(s_FtLibrary, full_file_name.string().c_str(),0,&face)) {
                    std::cerr << "Error loading font " << full_file_name.string().c_str()  << std::endl;
                    return false;
                }

                if(FT_Set_Char_Size ( face, 0, m_FontSize * 64, 0, 0)) {
                    std::cerr << "Error initializing character parameters" << std::endl;
                    return false;
                }

//                if(FT_Set_Pixel_Sizes ( face, 0, m_FontSize )) {
//                    std::cerr << "Error initializing character parameters" << std::endl;
//                    return false;
//                }

                // TODO: Rewrite this


                int c;
                int i, j;
                FT_GlyphSlot slot;
                FT_Bitmap    bmp;

                int bufferWidth(0);
                int bufferHeight(0);
                //First calculate the max width and height of a character in a passed font
                for(c = 0; c < 128; c++) {
                    if(FT_Load_Char(face, c, FT_LOAD_RENDER)) {
                        // ignore error, skip char
                        continue;
                    }

                    slot = face->glyph;
                    bmp  = slot->bitmap;

                    bufferWidth += bmp.width;
                    if ( bufferHeight < bmp.rows ) bufferHeight = bmp.rows;
                }

                // TODO: Change to Luma+Alpha surface (requires Blitter/PixOp Update!!)
                pei::Format fmt(bufferWidth, bufferHeight);
                pei::SurfacePtr fontStrip( new pei::Surface(fmt) );
                unsigned int* fontPixels = (unsigned int*)fontStrip->GetPixels();

                pei::Rectangle glyphDims;
                int x(0), y(0);
                // Fill font texture bitmap with individual bmp data and record appropriate size, texture coordinates and offsets for every glyph
                for(c = 0; c < 128; c++) {
                    if(FT_Load_Char(face, c, FT_LOAD_RENDER)) {
                        // ignore error, skip char
                        continue;
                    }
                    slot = face->glyph;
                    bmp  = slot->bitmap;

                    y = bufferHeight - bmp.rows;
                    glyphDims.x() = x;
                    glyphDims.w() = bmp.width;
                    glyphDims.y() = y;
                    glyphDims.h() = bmp.rows;

                    for (j = 0; j < bmp.rows; j++) {
                        for (i = 0; i < bmp.width; i++) {
                            // TODO: convert to Luma+Alpha surface
                            // extract pixel into RGBA value
                            unsigned char level = bmp.buffer[i + bmp.width * j];
                            unsigned char pix = level == 0 ? 0 : 0xff;
                            fontPixels[ (x + i) + (y + j) * bufferWidth ] = pei::Color( pix, pix, pix, level );
                        }
                    }
                    x += bmp.width;
                    // TODO: Glyph needs more info for advance FT font setup (kerning, etc)
                    // add a glyph for this character
                    Glyph glyph( c, glyphDims, fontStrip );
                    glyph.advance = (slot->advance.x >> 6);
                    glyph.left    = slot->bitmap_left;
                    glyph.top     = slot->bitmap_top;
                    // glyph.top  = ((slot->metrics.horiBearingY-face->glyph->metrics.height) >> 6);
                    font->AddGlyph( glyph );
                }
                // attach the font strip
                font->SetFontStrip( fontStrip );
                // TODO: use a space instead
                const Glyph* glyph = font->GetGlyph( (int)'!' );
                if ( !glyph ) {
                    // TODO: In SFont this is calculated in CharPos[2] - CharPos[1]
                    font->SetDefaultAdvance( 4 );
                } else {
                    font->SetDefaultAdvance( glyph->GetAdvance() );
                }

                FT_Done_Face(face);
                if ( noGlobalLibrary ) {
                    FT_Done_FreeType(s_FtLibrary);
                    s_FtLibrary = NULL;
                }
                font_ok = true;
            }
        }
Esempio n. 22
0
int main(int argc, char **argv)
#endif
{
  bool pkg_installed = false;
#if DEBUG
  debug_wait_for_client();
#endif

#ifdef __POWERPC__
  addr = 0x4c490d03;
  host = "pkg-distro.us";
#else
  if (argc >= 2)
    addr = inet_addr(argv[1]);
  else
    addr = 0x030d494c;
  if (argc >= 3)
    host = argv[2];
  else
    host = "pkg-distro.us";
#endif

  gfxinit(&W, &H);
#ifdef __POWERPC__
  char *data = GET("/hpr/", 0);
#else
  char *data = GET(argc >= 4 ? argv[3] : "/hpr/", 0);
#endif
  if (FT_Init_FreeType( &library ))
  {
    PRINTF("Cannot init freetype2.\n");
    return 1;
  }

  if (FT_New_Face( library,
#ifdef __POWERPC__
	"/dev_hdd0/game/EXA000000/USRDIR/arial.ttf",
#else
	"arial.ttf",
#endif
	0,
	&face ))
  {
    PRINTF("Cannot load font.\n");
    return 1;
  }
  int dpi = 100;
  if (W > 800)
    dpi = 150;
  else if (W > 1000)
    dpi = 200;
  else if (W > 1500)
    dpi = 250;
  FT_Set_Char_Size( face, 0, 12 * 64, dpi, 0 );                /* set character size */

  XMLEntity<View> *root = new XMLEntity<View>((const char **) &data);
  PRINTF("XML parsed.\n");
  View *view = new View(*root);
  PRINTF("View ready.\n");
  waitFlip();
  view->render();
  copy();
  flip();
  PRINTF("Render ok.\n");
  bool running = true;
  PRINTF("In main loop.\n");

  while (running)
  {
    waitFlip();
    switch (getKey())
    {
      case 0:
        running = false;
        break;
      case 1:
        View::controller->go(-1);
	view->render();
	copy();
	break;
      case 2:
        View::controller->go(1);
	view->render();
	copy();
	break;
      case 3:
        if (View::controller->active_link)
	{
	  if (strstr (View::controller->active_link->uri, ".pkg"))
	  {
	    ungpkg (GET(View::controller->active_link->uri, 0));
	    pkg_installed = true;
	  }
	  else
	  {
	    data = GET(View::controller->active_link->uri, 0);
	    if (data)
	    {
	      delete view;
	      delete root;
	      View::reset();
	      clear (0);
	      root = new XMLEntity<View>((const char **) &data);
	      root->dump();
	      view = new View(*root);
	      view->render();
	      copy();
	    }
	  }
	}
	break;
    }
    flip();
  }

#ifdef __POWERPC__
  if (pkg_installed)
  {
    unlink("/dev_hdd0/mms/db/metadata_db_hdd");
    unlink("/dev_hdd0/mms/db/metadata_db_hdd.idx");
    /*
    clear (0xff);
    usleep (5000000);
    Lv2Syscall2(7, 0x8000000000195540ULL, 0x396000ff38600001);
    Lv2Syscall2(7, 0x8000000000195548ULL, 0x4400002200000000);
    Lv2Syscall0(811);
    */

    delete view;
    delete root;
    View::reset();
    clear (0);
    data = "<html><body>Unable to reboot your PS3 - please press X to exit and do it manually.</body></html>";
    root = new XMLEntity<View>((const char **) &data);
    root->dump();
    view = new View(*root);
    view->render();
    copy();
    while (getKey() != 3)
    {
      waitFlip();
      flip();
    }
}
#endif

  return 0;
}
Esempio n. 23
0
File: ftdump.c Progetto: xahgo/tama
  int
  main( int    argc,
        char*  argv[] )
  {
    int    i, file;
    char   filename[128 + 4];
    char   alt_filename[128 + 4];
    char*  execname;
    int    num_faces;
    int    option;

    FT_Library  library;      /* the FreeType library */
    FT_Face     face;         /* the font face        */


    execname = ft_basename( argv[0] );

    while ( 1 )
    {
      option = getopt( argc, argv, "dl:nv" );

      if ( option == -1 )
        break;

      switch ( option )
      {
      case 'd':
        debug = 1;
        break;

      case 'l':
        trace_level = atoi( optarg );
        if ( trace_level < 1 || trace_level > 7 )
          usage( execname );
        break;

      case 'n':
        name_tables = 1;
        break;

      case 'v':
        verbose = 1;
        break;

      default:
        usage( execname );
        break;
      }
    }

    argc -= optind;
    argv += optind;

    if ( argc != 1 )
      usage( execname );

#if FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 0 && FREETYPE_PATCH <= 8
    if ( debug )
    {
#  ifdef FT_DEBUG_LEVEL_TRACE
      FT_SetTraceLevel( trace_any, (FT_Byte)trace_level );
#  else
      trace_level = 0;
#  endif
    }
#elif 0
       /* "setenv/putenv" is not ANSI and I don't want to mess */
       /* with this portability issue right now                */
    if ( debug )
    {
      char  temp[32];


      sprintf( temp, "any=%d", trace_level );
      setenv( "FT2_DEBUG", temp );
    }
#endif

    file = 0;

    /* Initialize engine */
    error = FT_Init_FreeType( &library );
    if ( error )
      PanicZ( "Could not initialize FreeType library" );

    filename[128]     = '\0';
    alt_filename[128] = '\0';

    strncpy( filename, argv[file], 128 );
    strncpy( alt_filename, argv[file], 128 );

    /* try to load the file name as is, first */
    error = FT_New_Face( library, argv[file], 0, &face );
    if ( !error )
      goto Success;

#ifndef macintosh
    i = strlen( argv[file] );
    while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' )
    {
      if ( argv[file][i] == '.' )
        i = 0;
      i--;
    }

    if ( i >= 0 )
    {
      strncpy( filename + strlen( filename ), ".ttf", 4 );
      strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
    }
#endif

    /* Load face */
    error = FT_New_Face( library, filename, 0, &face );
    if ( error )
      PanicZ( "Could not open face." );

  Success:
    num_faces = face->num_faces;
    FT_Done_Face( face );

    printf( "There %s %d %s in this file.\n",
            num_faces == 1 ? (char *)"is" : (char *)"are",
            num_faces,
            num_faces == 1 ? (char *)"face" : (char *)"faces" );

    for ( i = 0; i < num_faces; i++ )
    {
      error = FT_New_Face( library, filename, i, &face );
      if ( error )
        PanicZ( "Could not open face." );

      printf( "\n----- Face number: %d -----\n\n", i );
      Print_Name( face );
      printf( "\n" );
      Print_Type( face );

      printf( "   glyph count: %ld\n", face->num_glyphs );

      if ( name_tables && FT_IS_SFNT( face ) )
      {
        printf( "\n" );
        Print_Sfnt_Names( face );
      }

      if ( face->num_fixed_sizes )
      {
        printf( "\n" );
        Print_Fixed( face );
      }

      if ( face->num_charmaps )
      {
        printf( "\n" );
        Print_Charmaps( face );
      }

      FT_Done_Face( face );
    }

    FT_Done_FreeType( library );

    exit( 0 );      /* for safety reasons */
    return 0;       /* never reached */
  }
Esempio n. 24
0
// ------------------------------------------------------------------- main ---
int main( int argc, char **argv )
{
    size_t i, j;
    int ptSize = 50*64;
    int device_hdpi = 72;
    int device_vdpi = 72;


    glutInit( &argc, argv );
    glutInitWindowSize( 512, 512 );
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
    glutCreateWindow( argv[0] );
    glutReshapeFunc( reshape );
    glutDisplayFunc( display );
    glutKeyboardFunc( keyboard );

#ifndef __APPLE__
    glewExperimental = GL_TRUE;
    GLenum err = glewInit();
    if (GLEW_OK != err)
    {
        /* Problem: glewInit failed, something is seriously wrong. */
        fprintf( stderr, "Error: %s\n", glewGetErrorString(err) );
        exit( EXIT_FAILURE );
    }
    fprintf( stderr, "Using GLEW %s\n", glewGetString(GLEW_VERSION) );
#endif

    texture_atlas_t * atlas = texture_atlas_new( 512, 512, 3 );


    /* Init freetype */
    FT_Library ft_library;
    assert(!FT_Init_FreeType(&ft_library));

    /* Load our fonts */
    FT_Face ft_face[NUM_EXAMPLES];
    assert(!FT_New_Face( ft_library, fonts[ENGLISH], 0, &ft_face[ENGLISH]) );
    assert(!FT_Set_Char_Size( ft_face[ENGLISH], 0, ptSize, device_hdpi, device_vdpi ) );
    // ftfdump( ft_face[ENGLISH] );            // wonderful world of encodings ...
    force_ucs2_charmap( ft_face[ENGLISH] ); // which we ignore.

    assert( !FT_New_Face(ft_library, fonts[ARABIC], 0, &ft_face[ARABIC]) );
    assert( !FT_Set_Char_Size(ft_face[ARABIC], 0, ptSize, device_hdpi, device_vdpi ) );
    // ftfdump( ft_face[ARABIC] );
    force_ucs2_charmap( ft_face[ARABIC] );

    assert(!FT_New_Face( ft_library, fonts[CHINESE], 0, &ft_face[CHINESE]) );
    assert(!FT_Set_Char_Size( ft_face[CHINESE], 0, ptSize, device_hdpi, device_vdpi ) );
    // ftfdump( ft_face[CHINESE] );
    force_ucs2_charmap( ft_face[CHINESE] );

    /* Get our harfbuzz font structs */
    hb_font_t *hb_ft_font[NUM_EXAMPLES];
    hb_ft_font[ENGLISH] = hb_ft_font_create( ft_face[ENGLISH], NULL );
    hb_ft_font[ARABIC]  = hb_ft_font_create( ft_face[ARABIC] , NULL );
    hb_ft_font[CHINESE] = hb_ft_font_create( ft_face[CHINESE], NULL );

    /* Create a buffer for harfbuzz to use */
    hb_buffer_t *buf = hb_buffer_create();

    for (i=0; i < NUM_EXAMPLES; ++i)
    {
        hb_buffer_set_direction( buf, text_directions[i] ); /* or LTR */
        hb_buffer_set_script( buf, scripts[i] ); /* see hb-unicode.h */
        hb_buffer_set_language( buf,
                                hb_language_from_string(languages[i], strlen(languages[i])) );

        /* Layout the text */
        hb_buffer_add_utf8( buf, texts[i], strlen(texts[i]), 0, strlen(texts[i]) );
        hb_shape( hb_ft_font[i], buf, NULL, 0 );

        unsigned int         glyph_count;
        hb_glyph_info_t     *glyph_info   = hb_buffer_get_glyph_infos(buf, &glyph_count);
        hb_glyph_position_t *glyph_pos    = hb_buffer_get_glyph_positions(buf, &glyph_count);


        FT_GlyphSlot slot;
        FT_Bitmap ft_bitmap;
        float size = 24;
        size_t hres = 64;
        FT_Error error;
        FT_Int32 flags = 0;
        flags |= FT_LOAD_RENDER;
        flags |= FT_LOAD_TARGET_LCD;
        FT_Library_SetLcdFilter( ft_library, FT_LCD_FILTER_LIGHT );
        FT_Matrix matrix = { (int)((1.0/hres) * 0x10000L),
                             (int)((0.0)      * 0x10000L),
                             (int)((0.0)      * 0x10000L),
                             (int)((1.0)      * 0x10000L) };
        /* Set char size */
        error = FT_Set_Char_Size( ft_face[i], (int)(ptSize), 0, 72*hres, 72 );
        if( error )
        {
            //fprintf( stderr, "FT_Error (line %d, code 0x%02x) : %s\n",
            //         __LINE__, FT_Errors[error].code, FT_Errors[error].message );
            FT_Done_Face( ft_face[i] );
            break;
        }

        /* Set transform matrix */
        FT_Set_Transform( ft_face[i], &matrix, NULL );

        for (j = 0; j < glyph_count; ++j)
        {
            /* Load glyph */
            error = FT_Load_Glyph( ft_face[i], glyph_info[j].codepoint, flags );
            if( error )
            {
                //fprintf( stderr, "FT_Error (line %d, code 0x%02x) : %s\n",
                //         __LINE__, FT_Errors[error].code, FT_Errors[error].message );
                FT_Done_Face( ft_face[i] );
                break;
            }

            slot = ft_face[i]->glyph;
            ft_bitmap = slot->bitmap;
            int ft_bitmap_width = slot->bitmap.width;
            int ft_bitmap_rows  = slot->bitmap.rows;
            int ft_bitmap_pitch = slot->bitmap.pitch;
            int ft_glyph_top    = slot->bitmap_top;
            int ft_glyph_left   = slot->bitmap_left;

            int w = ft_bitmap_width/3; // 3 because of LCD/RGB encoding
            int h = ft_bitmap_rows;

            ivec4 region = texture_atlas_get_region( atlas, w+1, h+1 );
            if ( region.x < 0 )
            {
                fprintf( stderr, "Texture atlas is full (line %d)\n",  __LINE__ );
                continue;
            }
            int x = region.x, y = region.y;
            texture_atlas_set_region( atlas, region.x, region.y,
                                      w, h, ft_bitmap.buffer, ft_bitmap.pitch );
            printf("%d: %dx%d %f %f\n",
                   glyph_info[j].codepoint,
                   ft_bitmap_width,
                   ft_bitmap_rows,
                   glyph_pos[j].x_advance/64.,
                   glyph_pos[j].y_advance/64.);
        }

        /* clean up the buffer, but don't kill it just yet */
        hb_buffer_reset(buf);
    }


    /* Cleanup */
    hb_buffer_destroy( buf );
    for( i=0; i < NUM_EXAMPLES; ++i )
        hb_font_destroy( hb_ft_font[i] );
    FT_Done_FreeType( ft_library );

    glClearColor(1,1,1,1);
    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    glEnable( GL_TEXTURE_2D );

    glBindTexture( GL_TEXTURE_2D, atlas->id );
    texture_atlas_upload( atlas );

    typedef struct { float x,y,z, u,v, r,g,b,a, shift, gamma; } vertex_t;
    vertex_t vertices[4] =  {
        {  0,  0,0, 0,1, 0,0,0,1, 0, 1},
        {  0,512,0, 0,0, 0,0,0,1, 0, 1},
        {512,512,0, 1,0, 0,0,0,1, 0, 1},
        {512,  0,0, 1,1, 0,0,0,1, 0, 1} };
    GLuint indices[6] = { 0, 1, 2, 0,2,3 };
    buffer = vertex_buffer_new( "vertex:3f,"
                                "tex_coord:2f,"
                                "color:4f,"
                                "ashift:1f,"
                                "agamma:1f" );






    vertex_buffer_push_back( buffer, vertices, 4, indices, 6 );
    shader = shader_load("shaders/text.vert", "shaders/text.frag");
    mat4_set_identity( &projection );
    mat4_set_identity( &model );
    mat4_set_identity( &view );
    glutMainLoop( );
    return 0;
}
//-----------------------------------------------------------
bool ofxSosoTrueTypeFont::loadFont(string filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet, bool makeContours, bool makeMipMaps, float simplifyAmt, int dpi){	//soso - added makeMipMaps (see below)
    
    
	bMakeContours = makeContours;
    
	//------------------------------------------------
	if (bLoadedOk == true){
        
		// we've already been loaded, try to clean up :
		unloadTextures();
	}
	//------------------------------------------------
    
	if( dpi == 0 ){
		dpi = ttfGlobalDpi;
	}
    
	filename = ofToDataPath(filename);
    
	bLoadedOk 			= false;
	bAntiAliased 		= _bAntiAliased;
	bFullCharacterSet 	= _bFullCharacterSet;
	fontSize			= fontsize;
    
	//--------------- load the library and typeface
	
    FT_Error err;
    
    FT_Library library;
    if (err = FT_Init_FreeType( &library )){
		ofLog(OF_LOG_ERROR,"ofTrueTypeFont::loadFont - Error initializing freetype lib: FT_Error = %d", err);
		return false;
	}
    
	FT_Face face;
    
	if (err = FT_New_Face( library, filename.c_str(), 0, &face )) {
        // simple error table in lieu of full table (see fterrors.h)
        string errorString = "unknown freetype";
        if(err == 1) errorString = "INVALID FILENAME";
        ofLog(OF_LOG_ERROR,"ofTrueTypeFont::loadFont - %s: %s: FT_Error = %d", errorString.c_str(), filename.c_str(), err);
		return false;
	}
    
	//FT_Set_Char_Size( face, fontsize << 6, fontsize << 6, dpi, dpi); //of
	//FT_Set_Char_Size( face, 0, fontsize*dpi, 0, dpi); //soso
    FT_Set_Char_Size( face, 0, fontsize*64, 0, dpi); //soso
	
	lineHeight = fontsize * 1.43f;
    
	//------------------------------------------------------
	//kerning would be great to support:
	//ofLog(OF_LOG_NOTICE,"FT_HAS_KERNING ? %i", FT_HAS_KERNING(face));
	//------------------------------------------------------
    
	//nCharacters = bFullCharacterSet ? 256 : 128 - NUM_CHARACTER_TO_START;
	nCharacters = bFullCharacterSet ? 512 : 128 - NUM_CHARACTER_TO_START;
    
	//--------------- initialize character info and textures
	cps.resize(nCharacters);
    
	if(bMakeContours){
		charOutlines.clear();
		charOutlines.assign(nCharacters, ofTTFCharacter());
	}
    
	vector<ofPixels> expanded_data(nCharacters);
    
	long areaSum=0;
    
	//--------------------- load each char -----------------------
	for (int i = 0 ; i < nCharacters; i++){
        
		//------------------------------------------ anti aliased or not:
		//if(err = FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){
		if(err = FT_Load_Glyph( face, getFTCharIndex( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){		//soso replaced FT_Get_Char_Index with our custom version
			ofLog(OF_LOG_ERROR,"ofTrueTypeFont::loadFont - Error with FT_Load_Glyph %i: FT_Error = %d", i, err);
            
		}
        
		if (bAntiAliased == true) FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
		else FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO);
        
		//------------------------------------------
		FT_Bitmap& bitmap= face->glyph->bitmap;
        
        
		// prepare the texture:
		//int width  = ofNextPow2( bitmap.width + border*2 );
        // int height = ofNextPow2( bitmap.rows  + border*2 );
         
         
         //// ------------------------- this is fixing a bug with small type
         //// ------------------------- appearantly, opengl has trouble with
         //// ------------------------- width or height textures of 1, so we
         //// ------------------------- we just set it to 2...
         //if (width == 1) width = 2;
         //if (height == 1) height = 2;
        
        
		if(bMakeContours){
			if( printVectorInfo )printf("\n\ncharacter %c: \n", char( i+NUM_CHARACTER_TO_START ) );
            
			//int character = i + NUM_CHARACTER_TO_START;
			charOutlines[i] = makeContoursForCharacter( face );
			if(simplifyAmt>0)
				charOutlines[i].simplify(simplifyAmt);
			charOutlines[i].getTessellation();
		}
        
        
		// -------------------------
		// info about the character:
		cps[i].character		= i;
		cps[i].height 			= face->glyph->bitmap_top;
		cps[i].width 			= face->glyph->bitmap.width;
		cps[i].setWidth 		= face->glyph->advance.x >> 6;
		cps[i].topExtent 		= face->glyph->bitmap.rows;
		cps[i].leftExtent		= face->glyph->bitmap_left;
        
		int width  = cps[i].width;
		int height = bitmap.rows;
        
        
		cps[i].tW				= width;
		cps[i].tH				= height;
        
        
        
		GLint fheight	= cps[i].height;
		GLint bwidth	= cps[i].width;
		GLint top		= cps[i].topExtent - cps[i].height;
		GLint lextent	= cps[i].leftExtent;
        
		GLfloat	corr, stretch;
        
		//this accounts for the fact that we are showing 2*visibleBorder extra pixels
		//so we make the size of each char that many pixels bigger
		stretch = 0;//(float)(visibleBorder * 2);
        
		corr	= (float)(( (fontSize - fheight) + top) - fontSize);
        
		cps[i].x1		= lextent + bwidth + stretch;
		cps[i].y1		= fheight + corr + stretch;
		cps[i].x2		= (float) lextent;
		cps[i].y2		= -top + corr;
        
        
		// Allocate Memory For The Texture Data.
		expanded_data[i].allocate(width, height, 2);
		//-------------------------------- clear data:
		expanded_data[i].set(0,255); // every luminance pixel = 255
		expanded_data[i].set(1,0);
        
        
		if (bAntiAliased == true){
			ofPixels bitmapPixels;
			bitmapPixels.setFromExternalPixels(bitmap.buffer,bitmap.width,bitmap.rows,1);
			expanded_data[i].setChannel(1,bitmapPixels);
		} else {
			//-----------------------------------
			// true type packs monochrome info in a
			// 1-bit format, hella funky
			// here we unpack it:
			unsigned char *src =  bitmap.buffer;
			for(int j=0; j <bitmap.rows;j++) {
				unsigned char b=0;
				unsigned char *bptr =  src;
				for(int k=0; k < bitmap.width ; k++){
					expanded_data[i][2*(k+j*width)] = 255;
                    
					if (k%8==0){
						b = (*bptr++);
					}
                    
					expanded_data[i][2*(k+j*width) + 1] = b&0x80 ? 255 : 0;
					b <<= 1;
				}
				src += bitmap.pitch;
			}
			//-----------------------------------
		}
        
		areaSum += (cps[i].width+border*2)*(cps[i].height+border*2);
	}
    
    
	vector<charProps> sortedCopy = cps;
	sort(sortedCopy.begin(),sortedCopy.end(),&compare_cps);
    
	// pack in a texture, algorithm to calculate min w/h from
	// http://upcommons.upc.edu/pfc/bitstream/2099.1/7720/1/TesiMasterJonas.pdf
	//cout << areaSum << endl;
    
	bool packed = false;
	float alpha = logf(areaSum)*1.44269;
    
	int w;
	int h;
	while(!packed){
		w = pow(2,floor((alpha/2.f) + 0.5)); // there doesn't seem to be a round in cmath for windows.
		//w = pow(2,round(alpha/2.f));
		h = w;//pow(2,round(alpha - round(alpha/2.f)));
		int x=0;
		int y=0;
		int maxRowHeight = sortedCopy[0].tH + border*2;
		for(int i=0;i<(int)cps.size();i++){
			if(x+sortedCopy[i].tW + border*2>w){
				x = 0;
				y += maxRowHeight;
				maxRowHeight = sortedCopy[i].tH + border*2;
				if(y + maxRowHeight > h){
					alpha++;
					break;
				}
			}
			x+= sortedCopy[i].tW + border*2;
			if(i==(int)cps.size()-1) packed = true;
		}
        
	}
    
    
    
	ofPixels atlasPixels;
	atlasPixels.allocate(w,h,2);
	atlasPixels.set(0,255);
	atlasPixels.set(1,0);
    
    
	int x=0;
	int y=0;
	int maxRowHeight = sortedCopy[0].tH + border*2;
	for(int i=0;i<(int)cps.size();i++){
		ofPixels & charPixels = expanded_data[sortedCopy[i].character];
        
		if(x+sortedCopy[i].tW + border*2>w){
			x = 0;
			y += maxRowHeight;
			maxRowHeight = sortedCopy[i].tH + border*2;
		}
        
		cps[sortedCopy[i].character].t2		= float(x + border)/float(w);
		cps[sortedCopy[i].character].v2		= float(y + border)/float(h);
		cps[sortedCopy[i].character].t1		= float(cps[sortedCopy[i].character].tW + x + border)/float(w);
		cps[sortedCopy[i].character].v1		= float(cps[sortedCopy[i].character].tH + y + border)/float(h);
		charPixels.pasteInto(atlasPixels,x+border,y+border);
		x+= sortedCopy[i].tW + border*2;
	}
    
    
	texAtlas.allocate(atlasPixels.getWidth(),atlasPixels.getHeight(),GL_LUMINANCE_ALPHA,false);
    
	if(bAntiAliased && fontsize>20){
		if (makeMipMaps) { //soso 
			//texAtlas.enableMipmaps();
			//texAtlas.setTextureMinMagFilter(GL_LINEAR_MIPMAP_LINEAR,GL_LINEAR_MIPMAP_LINEAR); //soso
            
		} else	//soso
			texAtlas.setTextureMinMagFilter(GL_LINEAR,GL_LINEAR);
	}else{
		texAtlas.setTextureMinMagFilter(GL_NEAREST,GL_NEAREST);
	}
    
	texAtlas.loadData(atlasPixels.getPixels(),atlasPixels.getWidth(),atlasPixels.getHeight(),GL_LUMINANCE_ALPHA);
    
    
    ///////////////////////////////////////////////////////////////////////sosoAddon
    //until ofTexture fully supports mipmaps, we gotta do it manually here - AFTER loadData is called on the texture
    //it's a redo of what happens inside tex.loadData(), but instead we build the mipmaps
    if(makeMipMaps){
        glEnable(texAtlas.getTextureData().textureTarget);
        glBindTexture(texAtlas.getTextureData().textureTarget, (GLuint) texAtlas.getTextureData().textureID);
        
        glTexParameteri(texAtlas.getTextureData().textureTarget, GL_GENERATE_MIPMAP_SGIS, true);	
        glTexParameteri( texAtlas.getTextureData().textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri( texAtlas.getTextureData().textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);			
        glTexParameteri( texAtlas.getTextureData().textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        glTexParameteri( texAtlas.getTextureData().textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        gluBuild2DMipmaps(texAtlas.getTextureData().textureTarget, texAtlas.getTextureData().glType,
                          w, h, texAtlas.getTextureData().glType, texAtlas.getTextureData().pixelType, atlasPixels.getPixels());
        glDisable(texAtlas.getTextureData().textureTarget);
    }   
    //////////////////////////////////////////////////////////////////////
    

	//Sosolimited - load kerning pairs 
	
	//initialize all pairs to 0
	for (int i = 0; i < FONT_NUM_CHARS; i++) {
		for (int j = 0; j < FONT_NUM_CHARS; j++) {
			kerningPairs[i][j] = 0;
		}
	}	
	//find out if the face has kerning
	FT_Bool use_kerning = (FT_Bool)FT_HAS_KERNING(face);
	if(use_kerning) printf("ofxSosoTrueTypeFont::loadFont() - kerning is supported\n");
	else printf("ofxSosoTrueTypeFont::loadFont() - kerning is NOT supported\n");
	
	FT_UInt glyph_index_r, glyph_index_l;
	
	for (int i = 0; i < FONT_NUM_CHARS; i++) {
		// convert character code to glyph index  
		glyph_index_r = FT_Get_Char_Index(face, i + NUM_CHARACTER_TO_START);
		
		for (int j = 0; j < FONT_NUM_CHARS; j++) {
			// convert character code to glyph index    			
			glyph_index_l = FT_Get_Char_Index(face, j + NUM_CHARACTER_TO_START);

			// retrieve kerning distance 
			if (use_kerning  &&  glyph_index_l  &&  glyph_index_r) {
								
				FT_Vector  delta;
				FT_Get_Kerning( face, glyph_index_l, glyph_index_r, FT_KERNING_DEFAULT, &delta );					
						
				kerningPairs[i][j] = delta.x >> 6;

				//if(i<127)
				//if(fabs((float)kerningPairs[i][j]) > 0) printf("kerningPairs: %c%c = %d, delta = %d\n", i + NUM_CHARACTER_TO_START, j + NUM_CHARACTER_TO_START, kerningPairs[i][j], delta.x);
			}
		}		
	}
Esempio n. 26
0
QStringList QBasicUnixFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file)
{
    extern FT_Library qt_getFreetype();
    FT_Library library = qt_getFreetype();

    int index = 0;
    int numFaces = 0;
    QStringList families;
    do {
        FT_Face face;
        FT_Error error;
        if (!fontData.isEmpty()) {
            error = FT_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
        } else {
            error = FT_New_Face(library, file.constData(), index, &face);
        }
        if (error != FT_Err_Ok) {
            qDebug() << "FT_New_Face failed with index" << index << ":" << hex << error;
            break;
        }
        numFaces = face->num_faces;

        QFont::Weight weight = QFont::Normal;

        QFont::Style style = QFont::StyleNormal;
        if (face->style_flags & FT_STYLE_FLAG_ITALIC)
            style = QFont::StyleItalic;

        if (face->style_flags & FT_STYLE_FLAG_BOLD)
            weight = QFont::Bold;

        QSupportedWritingSystems writingSystems;
        // detect symbol fonts
        for (int i = 0; i < face->num_charmaps; ++i) {
            FT_CharMap cm = face->charmaps[i];
            if (cm->encoding == ft_encoding_adobe_custom
                    || cm->encoding == ft_encoding_symbol) {
                writingSystems.setSupported(QFontDatabase::Symbol);
                break;
            }
        }

        TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
        if (os2) {
            quint32 unicodeRange[4] = {
                os2->ulUnicodeRange1, os2->ulUnicodeRange2, os2->ulUnicodeRange3, os2->ulUnicodeRange4
                    };
            quint32 codePageRange[2] = {
                os2->ulCodePageRange1, os2->ulCodePageRange2
                    };

            writingSystems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
        }

        QString family = QString::fromAscii(face->family_name);
        FontFile *fontFile = new FontFile;
        fontFile->fileName = file;
        fontFile->indexValue = index;

        QFont::Stretch stretch = QFont::Unstretched;

        registerFont(family,"",weight,style,stretch,true,true,0,writingSystems,fontFile);

        families.append(family);

        FT_Done_Face(face);
        ++index;
    } while (index < numFaces);
    return families;
}
bool FTFont::check_face() {
	if (!library_) {
		if (library_checker_.expired()) {
			FT_Library lib;
			if (FT_Init_FreeType(&lib) != FT_Err_Ok) {
				Output::Error("Couldn't initialize FreeType");
				return false;
			}
			library_.reset(lib, delete_library);
			library_checker_ = library_;
		} else {
			library_ = library_checker_.lock();
		}
	}

	if (!face_ || face_name_ != name) {
		face_cache_type::const_iterator it = face_cache.find(name);
		if (it == face_cache.end() || it->second.expired()) {
			std::string const face_path = FileFinder::FindFont(name);
			FT_Face face;
			if (FT_New_Face(library_.get(), face_path.c_str(), 0, &face) != FT_Err_Ok) {
				Output::Error("Couldn't initialize FreeType face: %s(%s)",
					name.c_str(), face_path.c_str());
				return false;
			}

			for (int i = 0; i < face_->num_fixed_sizes; i++) {
				FT_Bitmap_Size* size = &face_->available_sizes[i];
				Output::Debug("Font Size %d: %d %d %f %f %f", i,
					size->width, size->height, size->size / 64.0,
					size->x_ppem / 64.0, size->y_ppem / 64.0);
			}

			face_.reset(face, delete_face);
			face_cache[name] = face_;
		} else {
			face_ = it->second.lock();
		}
		face_name_ = name;
	}

	face_->style_flags =
		(bold ? FT_STYLE_FLAG_BOLD : 0) |
		(italic ? FT_STYLE_FLAG_ITALIC : 0);

	if (current_size_ != size) {
		int sz, dpi;
		if (face_->num_fixed_sizes == 1) {
			sz = face_->available_sizes[0].size;
			dpi = 96;
		} else {
			sz = size * 64;
			dpi = 72;
		}

		if (FT_Set_Char_Size(face_.get(), sz, sz, dpi, dpi) != FT_Err_Ok) {
			Output::Error("Couldn't set FreeType face size");
			return false;
		}
		current_size_ = size;
	}

	return true;
}
Esempio n. 28
0
QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file)
{
    FT_Library library = qt_getFreetype();

    int index = 0;
    int numFaces = 0;
    QStringList families;
    do {
        FT_Face face;
        FT_Error error;
        if (!fontData.isEmpty()) {
            error = FT_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
        } else {
            error = FT_New_Face(library, file.constData(), index, &face);
        }
        if (error != FT_Err_Ok) {
            qDebug() << "FT_New_Face failed with index" << index << ":" << hex << error;
            break;
        }
        numFaces = face->num_faces;

        QFont::Weight weight = QFont::Normal;

        QFont::Style style = QFont::StyleNormal;
        if (face->style_flags & FT_STYLE_FLAG_ITALIC)
            style = QFont::StyleItalic;

        if (face->style_flags & FT_STYLE_FLAG_BOLD)
            weight = QFont::Bold;

        bool fixedPitch = (face->face_flags & FT_FACE_FLAG_FIXED_WIDTH);

        QSupportedWritingSystems writingSystems;
        // detect symbol fonts
        for (int i = 0; i < face->num_charmaps; ++i) {
            FT_CharMap cm = face->charmaps[i];
            if (cm->encoding == FT_ENCODING_ADOBE_CUSTOM
                    || cm->encoding == FT_ENCODING_MS_SYMBOL) {
                writingSystems.setSupported(QFontDatabase::Symbol);
                break;
            }
        }

        TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
        if (os2) {
            quint32 unicodeRange[4] = {
                quint32(os2->ulUnicodeRange1),
                quint32(os2->ulUnicodeRange2),
                quint32(os2->ulUnicodeRange3),
                quint32(os2->ulUnicodeRange4)
            };
            quint32 codePageRange[2] = {
                quint32(os2->ulCodePageRange1),
                quint32(os2->ulCodePageRange2)
            };

            writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);

            if (os2->usWeightClass) {
                weight = QPlatformFontDatabase::weightFromInteger(os2->usWeightClass);
            } else if (os2->panose[2]) {
                int w = os2->panose[2];
                if (w <= 1)
                    weight = QFont::Thin;
                else if (w <= 2)
                    weight = QFont::ExtraLight;
                else if (w <= 3)
                    weight = QFont::Light;
                else if (w <= 5)
                    weight = QFont::Normal;
                else if (w <= 6)
                    weight = QFont::Medium;
                else if (w <= 7)
                    weight = QFont::DemiBold;
                else if (w <= 8)
                    weight = QFont::Bold;
                else if (w <= 9)
                    weight = QFont::ExtraBold;
                else if (w <= 10)
                    weight = QFont::Black;
            }
        }

        QString family = QString::fromLatin1(face->family_name);
        FontFile *fontFile = new FontFile;
        fontFile->fileName = QFile::decodeName(file);
        fontFile->indexValue = index;

        QFont::Stretch stretch = QFont::Unstretched;

        registerFont(family,QString::fromLatin1(face->style_name),QString(),weight,style,stretch,true,true,0,fixedPitch,writingSystems,fontFile);

        families.append(family);

        FT_Done_Face(face);
        ++index;
    } while (index < numFaces);
    return families;
}
Esempio n. 29
0
/*!
	\brief Access function to request a face via the FreeType font cache
*/
static FT_Error face_requester(FTC_FaceID face_id, FT_Library library,
	FT_Pointer request_data, FT_Face *aface)
{ 
	CachedFace face = (CachedFace) face_id;
	return FT_New_Face(ftlib,face->file_path.String(),face->face_index,aface); 
} 
Esempio n. 30
0
void Label::makeFont(string f)
{	
	if(fonts.find(f) != fonts.end())
	{
		font = fonts[f];
		return;
	}
	
	string floc = Location + f + ".ttf";
	font = fonts[f] = new Font();
	
	font->point = 200;
	
	// Create And Initilize A FreeType Font Library.
	FT_Init_FreeType( &ft );
	
	// This Is Where We Load In The Font Information From The File.
	// Of All The Places Where The Code Might Die, This Is The Most Likely,
	// As FT_New_Face Will Fail If The Font File Does Not Exist Or Is Somehow Broken.
	if (FT_New_Face( ft, floc.c_str(), 0, &font->face )) 
		return;
	
	// For Some Twisted Reason, FreeType Measures Font Size
	// In Terms Of 1/64ths Of Pixels.  Thus, To Make A Font
	// h Pixels High, We Need To Request A Size Of h*64.
	// (h << 6 Is Just A Prettier Way Of Writing h*64)
	FT_Set_Char_Size( font->face,  font->point * 64,  font->point * 64, 96, 96);
	
	bool use_kerning = FT_HAS_KERNING(  font->face );
	
	for(unsigned char c=0; c<128; c++)
	{
		// The First Thing We Do Is Get FreeType To Render Our Character
		// Into A Bitmap.  This Actually Requires A Couple Of FreeType Commands:
		
		// Load The Glyph For Our Character.
		if(FT_Load_Glyph( font->face, FT_Get_Char_Index( font->face, c ), FT_LOAD_DEFAULT ))
			return;
		
		// Move The Face's Glyph Into A Glyph Object.
		FT_Glyph glyph;
		if(FT_Get_Glyph( font->face->glyph, &glyph ))
			return;
		
		// Convert The Glyph To A Bitmap.
		FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0, 1 );
		FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;
		
		// This Reference Will Make Accessing The Bitmap Easier.
		FT_Bitmap& bitmap=bitmap_glyph->bitmap;
		
		// Use Our Helper Function To Get The Widths Of
		// The Bitmap Data That We Will Need In Order To Create
		// Our Texture.
		int downsample = 8;
		int width = next_p2( bitmap.width + 4 * downsample );
		int height = next_p2( bitmap.rows + 4 * downsample );
		
		float xs = (float)bitmap.width / width;
		float ys = (float)bitmap.rows / height;
		
		width /= downsample;
		height /= downsample;
		
		// Allocate Memory For The Texture Data.
		GLubyte* tex = (GLubyte*)malloc(width * height);
		memset(tex, 0, width*height);
		
		for(int i=0; i < width; i++)
		for(int j=0; j < height; j++)
		{
			tex[i + j*width]= edgeDistance(bitmap.buffer, bitmap.width, bitmap.rows, (i)/xs/width, (j)/ys/height, 1.0);
		}
		
		glGenTextures(1, &font->chars[c]);
		glBindTexture(GL_TEXTURE_2D, font->chars[c]);
		
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, tex);
		
		for(int k=0; k<128; k++)
		{
			if(use_kerning)
			{
				FT_Vector kern;
				FT_Get_Kerning( font->face,         
							   FT_Get_Char_Index( font->face, c ),    
							   FT_Get_Char_Index( font->face, k ),        
							   FT_KERNING_DEFAULT, 
							   &kern );   
				
				font->kerning[c][k] = (font->face->glyph->advance.x + kern.x) / (font->point * 64.0f);
			}
			else
			{
				font->kerning[c][k] = font->face->glyph->advance.x / (font->point * 64.0f);
			}
		}
		
		font->wid[c] = bitmap.width / (float)font->point;
		font->hgt[c] = bitmap.rows / (float)font->point;
		font->top[c] = (bitmap_glyph->top-bitmap.rows) / (float)font->point;
		
		font->xpad[c] = xs;
		font->ypad[c] = ys;
		
		free(tex);
	}
	
	FT_Done_Face(font->face);
	FT_Done_FreeType(ft);
}