/******************************************************************************
*
* Copyright (c) 2015 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer.
*
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* FreeTypeFont.h
*
*****************************************************************************/
#pragma once
#include <oz++/motif/DC.h>
#include <oz++/freetype/FreeTypeLibrary.h>
/*
typedef struct FT_FaceRec_
{
FT_Long num_faces;
FT_Long face_index;
FT_Long face_flags;
FT_Long style_flags;
FT_Long num_glyphs;
FT_String* family_name;
FT_String* style_name;
FT_Int num_fixed_sizes;
FT_Bitmap_Size* available_sizes;
FT_Int num_charmaps;
FT_CharMap* charmaps;
FT_Generic generic;
FT_BBox bbox;
FT_UShort units_per_EM;
FT_Short ascender;
FT_Short descender;
FT_Short height;
FT_Short max_advance_width;
FT_Short max_advance_height;
FT_Short underline_position;
FT_Short underline_thickness;
FT_GlyphSlot glyph;
FT_Size size;
FT_CharMap charmap;
//@private begin
FT_Driver driver;
FT_Memory memory;
FT_Stream stream;
FT_ListRec sizes_list;
FT_Generic autohint;
void* extensions;
FT_Face_Internal internal;
//private end
} FT_FaceRec;
*/
//typedef struct FT_FaceRec_* FT_Face;
namespace OZ {
class FreeTypeFont :public FreeTypeObject {
private:
FreeTypeLibrary* library;
FT_Face face;
public:
FreeTypeFont( FreeTypeLibrary* library, const char* filePathname,
FT_Long faceIndex = 0)
:library(library),
face(NULL)
{
if (library == NULL || filePathname == NULL) {
throw IException("Invalid argument");
}
if (FT_New_Face(library->get(),
filePathname,
faceIndex,
&face) ) {
throw IException("Failed FT_New_Face");
}
}
public:
FreeTypeFont( FreeTypeLibrary* library,
const FT_Byte* file_base,
FT_Long file_size,
FT_Long face_index )
:library(library),
face(NULL)
{
if (library == NULL || file_base == NULL) {
throw IException("Invalid argument");
}
if (FT_New_Memory_Face( library -> get(),
file_base,
file_size,
face_index,
&face )) {
throw IException("Failed to FT_New_Memory_Face");
}
}
/*
typedef struct FT_Open_Args_
{
FT_UInt flags;
const FT_Byte* memory_base;
FT_Long memory_size;
FT_String* pathname;
FT_Stream stream;
FT_Module driver;
FT_Int num_params;
FT_Parameter* params;
} FT_Open_Args;
*/
public:
FreeTypeFont( FreeTypeLibrary* library,
const FT_Open_Args* args,
FT_Long faceIndex)
:library(library),
face(NULL)
{
if (library == NULL || args == NULL) {
throw IException("Invalid argument");
}
if (FT_Open_Face(library->get(),
args,
faceIndex,
&face) )
{
throw IException("Failed FT_Open_Face");
}
}
~FreeTypeFont()
{
if (face) {
if (FT_Done_Face(face)) {
printf("Failed to FT_Done_Face");
}
}
}
void attachFile( const char* filePathname )
{
if (FT_Attach_File(face, filePathname )) {
throw IException("Faield to FT_Attach_File");
}
}
void attachStream( FT_Open_Args* parameters )
{
if (FT_Attach_Stream( face, parameters )) {
throw IException("Failed to FT_Attach_Stream");
}
}
void referenceFace( )
{
if (FT_Reference_Face( face )) {
throw IException("FT_Reference_Face");
}
}
void setCharSize( FT_F26Dot6 char_width,
FT_F26Dot6 char_height,
FT_UInt horz_resolution,
FT_UInt vert_resolution )
{
if (FT_Set_Char_Size( face,
char_width,
char_height,
horz_resolution,
vert_resolution )) {
throw IException("FT_Set_Char_Size");
}
}
void setPixelSizes( FT_UInt pixel_width,
FT_UInt pixel_height )
{
if (FT_Set_Pixel_Sizes( face,
pixel_width,
pixel_height )) {
throw IException("Failed to FT_Set_Pixel_Sizes");
}
}
void setPixelHeight( FT_UInt pixel_height )
{
setPixelSizes( 0, pixel_height );
}
//Resize the scale of the active FT_Size object in a face.
void requestSize( FT_Size_Request req )
{
if ( FT_Request_Size(face, req )) {
throw IException("Failed to FT_Request_Size");
}
}
void selectSize( FT_Int strikeIndex )
{
if ( FT_Select_Size(face, strikeIndex )) {
throw IException("Failed to FT_Select_Size");
}
}
void setTransform( FT_Matrix* matrix, FT_Vector* delta )
{
FT_Set_Transform( face,
matrix,
delta );
}
FT_UInt getCharIndex(const char ch)
{
return FT_Get_Char_Index(face, ch);
}
FT_UInt getCharIndex(const wchar_t ch)
{
return FT_Get_Char_Index(face, ch);
}
//FT_LOAD_RENDER indicates that the glyph image must be immediately
//converted to an anti-aliased bitmap
void loadGlyph( FT_UInt glyph_index, FT_Int32 load_flags=FT_LOAD_RENDER)
{
if (FT_Load_Glyph(face, glyph_index, load_flags )) {
throw IException("Failed to FT_Load_Glyph");
}
}
void loadGlyph(const char ch, FT_Int32 load_flags )
{
FT_UInt index = getCharIndex(ch);
if (FT_Load_Glyph(face, index, load_flags )) {
throw IException("Failed to FT_Load_Glyph");
}
}
void loadGlyph( const wchar_t ch, FT_Int32 load_flags )
{
FT_UInt index = getCharIndex(ch);
if (FT_Load_Glyph(face, index, load_flags )) {
throw IException("Failed to FT_Load_Glyph");
}
}
void loadMonochromeGlyph( const char ch )
{
FT_UInt index = getCharIndex(ch);
FT_Int32 load_flags=FT_LOAD_RENDER|FT_LOAD_MONOCHROME;
if (FT_Load_Glyph(face, index, load_flags )) {
throw IException("Failed to FT_Load_Glyph");
}
}
void loadMonochromeGlyph( const wchar_t ch )
{
FT_UInt index = getCharIndex(ch);
FT_Int32 load_flags=FT_LOAD_RENDER|FT_LOAD_MONOCHROME;
if (FT_Load_Glyph(face, index, load_flags )) {
throw IException("Failed to FT_Load_Glyph");
}
}
void getCharIndex( FT_ULong charcode )
{
if (FT_Get_Char_Index( face, charcode )) {
throw IException("FT_Get_Char_Index");
}
}
FT_ULong getFirstChar(FT_UInt *agindex )
{
return FT_Get_First_Char( face, agindex );
}
FT_ULong getNextChar( FT_ULong char_code, FT_UInt *agindex )
{
return FT_Get_Next_Char( face, char_code, agindex );
}
FT_UInt getNameIndex( FT_String* glyph_name )
{
return FT_Get_Name_Index( face, glyph_name );
}
FT_Long getFaceFlags()
{
return face -> face_flags;
}
FT_Long getStyleFlags()
{
return face -> style_flags;
}
FT_Long getNumGlypsh()
{
return face -> num_glyphs;
}
FT_String* getFamilyName()
{
return face -> family_name;
}
FT_String* getStyleName()
{
return face -> style_name;
}
void loadChar( FT_ULong char_code, FT_Int32 load_flags )
{
if (FT_Load_Char( face, char_code, load_flags )) {
throw IException("Failed to FT_Load_Char");
}
}
void setCharmap( FT_CharMap charmap )
{
if (FT_Set_Charmap( face, charmap )) {
throw IException("FT_Set_Charmap");
}
}
FT_UShort getFSTypeFlags( )
{
return FT_Get_FSType_Flags( face );
}
void getKerning( FT_UInt left_glyph,
FT_UInt right_glyph,
FT_UInt kern_mode,
FT_Vector *akerning )
{
if (FT_Get_Kerning(face,
left_glyph,
right_glyph,
kern_mode,
akerning )) {
throw IException("Failed to FT_Get_Kerning");
}
}
void getTrackKerning( FT_Fixed point_size,
FT_Int degree,
FT_Fixed* akerning )
{
if (FT_Get_Track_Kerning( face,
point_size,
degree,
akerning )) {
throw IException("Failed to FT_Get_Tracking");
}
}
void getGlyphName( FT_UInt glyph_index,
FT_Pointer buffer,
FT_UInt buffer_max )
{
if (FT_Get_Glyph_Name( face,
glyph_index,
buffer,
buffer_max )) {
throw IException("Failed to FT_Get_Glyph_Name");
}
}
/*
typedef struct FT_GlyphSlotRec_
{
FT_Library library;
FT_Face face;
FT_GlyphSlot next;
FT_UInt reserved;
FT_Generic generic;
FT_Glyph_Metrics metrics;
FT_Fixed linearHoriAdvance;
FT_Fixed linearVertAdvance;
FT_Vector advance;
FT_Glyph_Format format;
FT_Bitmap bitmap;
FT_Int bitmap_left;
FT_Int bitmap_top;
FT_Outline outline;
FT_UInt num_subglyphs;
FT_SubGlyph subglyphs;
void* control_data;
long control_len;
FT_Pos lsb_delta;
FT_Pos rsb_delta;
void* other;
FT_Slot_Internal internal;
} FT_GlyphSlotRec;
*/
FT_GlyphSlot getGlyphSlot()
{
return face -> glyph;
}
FT_Int getBitmapLeft()
{
FT_GlyphSlot slot = getGlyphSlot();
return slot -> bitmap_left;
}
FT_Int getBitmapTop()
{
FT_GlyphSlot slot = getGlyphSlot();
return slot -> bitmap_top;
}
FT_Vector getAdvance()
{
FT_GlyphSlot slot = getGlyphSlot();
return slot -> advance;
}
FT_Glyph_Metrics getGlyphMetrics()
{
FT_GlyphSlot slot = getGlyphSlot();
return slot -> metrics;
}
FT_SubGlyph getSubGlyph(FT_UInt& num_subglyphs)
{
FT_GlyphSlot slot = getGlyphSlot();
num_subglyphs = slot -> num_subglyphs;
return slot -> subglyphs;
}
FT_UShort getUnitsPerEM()
{
return face -> units_per_EM;
}
FT_Short getAscender()
{
return face -> ascender;
}
FT_Short getDescender()
{
return face -> descender;
}
FT_Short getHeight()
{
return face -> height;
}
FT_Short getMaxAdvanceWidth()
{
return face -> max_advance_width;
}
FT_Short getMaxAdvanceHeight()
{
return face -> max_advance_height;
}
FT_Short getUnderlinePosition()
{
return face -> underline_position;
}
FT_Short getUnderlineThickness()
{
return face -> underline_thickness;
}
/*
typedef struct FT_Bitmap_
{
unsigned int rows;
unsigned int width;
int pitch;
unsigned char* buffer;
unsigned short num_grays;
unsigned char pixel_mode;
unsigned char palette_mode;
void* palette;
} FT_Bitmap;
*/
FT_Bitmap getBitmap()
{
FT_GlyphSlot slot = getGlyphSlot();
return slot -> bitmap;
}
FT_Int getBitmapRows()
{
FT_GlyphSlot slot = getGlyphSlot();
return slot -> bitmap.rows;
}
FT_Int getBitmapWidth()
{
FT_GlyphSlot slot = getGlyphSlot();
return slot -> bitmap.width;
}
unsigned char* getBitmapBuffer()
{
FT_GlyphSlot slot = getGlyphSlot();
return slot -> bitmap.buffer;
}
FT_CharMap* getCharMap(FT_Int& numCharmaps)
{
numCharmaps = face -> num_charmaps;
return face -> charmaps;
}
};
}