Esempio n. 1
0
/*!	\brief Adds the FontFamily/FontStyle that is represented by this path.
*/
status_t
FontManager::_AddFont(font_directory& directory, BEntry& entry)
{
	node_ref nodeRef;
	status_t status = entry.GetNodeRef(&nodeRef);
	if (status < B_OK)
		return status;

	BPath path;
	status = entry.GetPath(&path);
	if (status < B_OK)
		return status;

	FT_Face face;
	FT_Error error = FT_New_Face(gFreeTypeLibrary, path.Path(), 0, &face);
	if (error != 0)
		return B_ERROR;

	FontFamily *family = _FindFamily(face->family_name);
	if (family != NULL && family->HasStyle(face->style_name)) {
		// prevent adding the same style twice
		// (this indicates a problem with the installed fonts maybe?)
		FT_Done_Face(face);
		return B_OK;
	}

	if (family == NULL) {
		family = new (std::nothrow) FontFamily(face->family_name, fNextID++);
		if (family == NULL
			|| !fFamilies.BinaryInsert(family, compare_font_families)) {
			delete family;
			FT_Done_Face(face);
			return B_NO_MEMORY;
		}
	}

	FTRACE(("\tadd style: %s, %s\n", face->family_name, face->style_name));

	// the FontStyle takes over ownership of the FT_Face object
	FontStyle *style = new FontStyle(nodeRef, path.Path(), face);
	if (!family->AddStyle(style)) {
		delete style;
		delete family;
		return B_NO_MEMORY;
	}

	directory.styles.AddItem(style);
	fStyleHashTable.AddItem(style);

	if (directory.AlreadyScanned())
		directory.revision++;

	return B_OK;
}
Esempio n. 2
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;
}