Aros/Developer/Docs/Libraries/FreeType2

Introduction

Provides TrueType, OpenType and Type 1 font and glyphs support for AROS.



↑Jump back a section

Examples

link with -lfreetype2

#include <diskfont/glyph.h>
#include <utility/tagitem.h>


#include <aros/debug.h>
#include <libraries/mui.h>
#include <graphics/gfx.h>
#include <diskfont/diskfonttag.h>
 
#include <proto/alib.h>
#include <proto/exec.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/utility.h>
#include <proto/muimaster.h>
#include <proto/freetype2.h>
 
#include <string.h>
 
#include "fontbitmap_class.h"
#include "globals.h"
 
struct FontBitmapData
{
        int Width, Height;
        struct BitMap BitMap;
        struct BitMap *GrayBitMap;
};
 
typedef struct FontBitmapData FontBitmapData;
 
IPTR fbNew(Class *cl, Object *o, struct opSet *msg)
{
        struct opSet method;
        struct TagItem tags[5];
        STRPTR filename = (STRPTR)GetTagData(MUIA_FontBitmap_Filename, (IPTR) NULL, msg->ops_AttrList);
        STRPTR string = (STRPTR)GetTagData(MUIA_FontBitmap_String, (IPTR) "?", msg->ops_AttrList);
        struct TagItem *otags = (struct TagItem *)GetTagData(MUIA_FontBitmap_OTags,
                        (IPTR) NULL, msg->ops_AttrList);
        struct
        {
                struct GlyphMap *glyph;
                int x;
                int y;
        } *info;
        APTR engine;
        struct BitMap bitmap;
        struct BitMap *gray_bitmap = NULL;
        int width, height;
        int length = strlen(string);
        int x, y, k;
        int xmin, xmax, ymin, ymax;
        int space_width, size, gray;
        int previous;
        Tag tag;
 
        if (filename == NULL)
        {
                DEBUG_FONTBITMAP(dprintf("FontBitmap: no filename.\n"));
                return 0;
        }
 
        engine = OpenEngine();
        if (engine == NULL)
        {
                DEBUG_FONTBITMAP(dprintf("FontBitmap: no engine.\n"));
                return 0;
        }
 
        size = GetTagData(MUIA_FontBitmap_Size, 30, msg->ops_AttrList);
        gray = GetTagData(MUIA_FontBitmap_Gray, FALSE, msg->ops_AttrList);
 
        SetInfo(engine,
                        OT_OTagList, (IPTR) otags,
                        OT_DeviceDPI, 72 | (72 << 16),
                        OT_PointHeight, size << 16,
                        TAG_END);
 
        space_width = (int)(GetTagData(OT_SpaceWidth, 0, otags) / 65536.0 * size) ;
 
        info = AllocVec(length * sizeof(*info), MEMF_CLEAR);
        if (info == NULL)
        {
                DEBUG_FONTBITMAP(dprintf("FontBitmap: can't alloc glyphs.\n"));
                length = 0;
        }
 
        x = 0;
        y = 0;
        previous = 0;
        xmin = ymin = 0x7fffffff;
        xmax = ymax = -0x80000000;
        tag = gray ? OT_GlyphMap8Bit : OT_GlyphMap;
 
        for (k = 0; k < length; ++k)
        {
                int code = string[k];
                int x1, y1, x2, y2;
                struct GlyphMap *g;
 
                if (previous)
                {
                        ULONG kerning;
 
                        SetInfo(engine,
                                        OT_GlyphCode, previous,
                                        OT_GlyphCode2, code,
                                        TAG_END);
                        ObtainInfo(engine,
                                        OT_TextKernPair, (IPTR)&kerning,
                                        TAG_END);
 
                        x -= (int)(kerning / 65536.0 * size);
                }
 
                info[k].x = x;
                info[k].y = y;
 
                SetInfo(engine,
                                OT_GlyphCode, code,
                                TAG_END);
                ObtainInfo(engine,
                                tag, (IPTR)&info[k].glyph,
                                TAG_END);
 
                g = info[k].glyph;
 
                if (!g)
                {
                        x += space_width;
                        continue;
                }
 
                x1 = x - g->glm_X0 + g->glm_BlackLeft;
                y1 = y - g->glm_Y0 + g->glm_BlackTop;
                x2 = x1 + g->glm_BlackWidth;
                y2 = y1 + g->glm_BlackHeight;
 
                if (x1 < xmin)
                        xmin = x1;
                if (y1 < ymin)
                        ymin = y1;
                if (x2 > xmax)
                        xmax = x2;
                if (y2 > ymax)
                        ymax = y2;
 
                x += g->glm_X1 - g->glm_X0;
                y += g->glm_Y1 - g->glm_Y0;
 
                previous = code;
        }
 
        width = xmax - xmin + 1;
        height = ymax - ymin + 1;
 
        DEBUG_FONTBITMAP(dprintf("FontBitmap: bbox %d %d %d %d\n", xmin, ymin, xmax, ymax));
        DEBUG_FONTBITMAP(dprintf("FontBitmap: width %d height %d\n", width, height));
 
        if (width > 0 && height > 0 && width < 32000 && height < 32000)
        {
                if (gray)
                {
                        UBYTE *array;
                        int width1 = (width + 15) & ~15;
 
                        array = AllocVec(width1 * height, MEMF_CLEAR);
                        if (array)
                        {
                                for (k = 0; k < length; ++k)
                                {
                                        struct GlyphMap *g = info[k].glyph;
                                        int x1, x2, y1, y2;
                                        UBYTE *p;
 
                                        if (!g)
                                        {
                                                x += space_width;
                                                continue;
                                        }
 
                                        x = info[k].x - xmin;
                                        y = info[k].y - ymin;
                                        x -= g->glm_X0;
                                        y -= g->glm_Y0;
                                        x += g->glm_BlackLeft;
                                        y += g->glm_BlackTop;
 
                                        p = g->glm_BitMap;
                                        x1 = x;
                                        y1 = y;
                                        x2 = x + g->glm_BlackWidth;
                                        y2 = y + g->glm_BlackHeight;
 
                                        if (x1 > width || x2 < 0 || y1 > height || y2 < 0)
                                                continue;
 
                                        if (x1 < 0)
                                        {
                                                p -= x1;
                                                x1 = 0;
                                        }
                                        if (y1 < 0)
                                        {
                                                p -= y1 * g->glm_BMModulo;
                                                y1 = 0;
                                        }
                                        if (x2 > width)
                                        {
                                                x2 = width;
                                        }
                                        if (y2 > height)
                                        {
                                                y2 = height;
                                        }
 
                                        while (y1 < y2)
                                        {
                                                int x;
 
                                                for (x = x1; x < x2; ++x)
                                                {
                                                        int t = array[width1 * y1 + x] + p[x - x1];
                                                        if (t > 255)
                                                                t = 255;
                                                        array[width1 * y1 + x] = t;
                                                }
                                                p += g->glm_BMModulo;
                                                ++y1;
                                        }
                                }
 
                                gray_bitmap = AllocBitMap(width, height, 8, 0, NULL);
                                if (gray_bitmap)
                                {
                                        struct RastPort rp, tmp_rp;
 
                                        InitRastPort(&rp);
                                        InitRastPort(&tmp_rp);
 
                                        rp.BitMap = gray_bitmap;
                                        tmp_rp.BitMap = AllocBitMap(width, 1, 8, 0, NULL);
 
                                        if (tmp_rp.BitMap)
                                        {
                                                WritePixelArray8(&rp,
                                                                0,
                                                                0,
                                                                width - 1,
                                                                height - 1,
                                                                array,
                                                                &tmp_rp);
                                                FreeBitMap(tmp_rp.BitMap);
                                        }
                                }
 
                                FreeVec(array);
                        }
                }
                else
                {
                        InitBitMap(&bitmap, 1, width, height);
                        bitmap.Planes[0] = AllocRaster(width, height);
 
                        if (bitmap.Planes[0])
                        {
                                struct RastPort rp;
 
                                InitRastPort(&rp);
                                rp.BitMap = &bitmap;
                                SetRast(&rp, 0);
                                SetAPen(&rp, 1);
                                SetDrMd(&rp, JAM1);
 
                                for (k = 0; k < length; ++k)
                                {
                                        struct GlyphMap *g = info[k].glyph;
 
                                        if (!g)
                                                continue;
 
                                        x = info[k].x - xmin;
                                        y = info[k].y - ymin;
                                        x -= g->glm_X0;
                                        y -= g->glm_Y0;
                                        x += g->glm_BlackLeft;
                                        y += g->glm_BlackTop;
 
                                        /* glm_BitMap is not in chip mem.
                                         * Oh well.
                                         */
                                        BltTemplate((const PLANEPTR)(g->glm_BitMap +
                                                                g->glm_BMModulo *
                                                                g->glm_BlackTop),
                                                        g->glm_BlackLeft,
                                                        g->glm_BMModulo,
                                                        &rp,
                                                        x, y,
                                                        g->glm_BlackWidth,
                                                        g->glm_BlackHeight);
                                }
                        }
                }
 
                tags[0].ti_Tag = MUIA_Bitmap_Width;
                tags[0].ti_Data = width;
                tags[1].ti_Tag = MUIA_Bitmap_Height;
                tags[1].ti_Data = height;
                tags[2].ti_Tag = MUIA_FixWidth;
                tags[2].ti_Data = width;
                tags[3].ti_Tag = MUIA_FixHeight;
                tags[3].ti_Data = height;
                tags[4].ti_Tag = TAG_MORE;
                tags[4].ti_Data = (IPTR)msg->ops_AttrList;
 
                method.MethodID = OM_NEW;
                method.ops_AttrList = tags;
                method.ops_GInfo = NULL;
 
                o = (Object *)DoSuperMethodA(cl, o, (Msg)&method);
 
                if (o)
                {
                        FontBitmapData *dat = INST_DATA(cl, o);
 
                        dat->Width = width;
                        dat->Height = height;
                        dat->GrayBitMap = gray_bitmap;
 
                        if (gray)
                        {
                                static ULONG colors[256 * 3];
                                static BOOL init;
 
                                if (!init)
                                {
                                        int k;
                                        ULONG *p = colors;
                                        for (k = 256; --k >= 0; p += 3)
                                        {
                                                p[0] = p[1] = p[2] = k * 0x01010101;
                                        }
                                        init = TRUE;
                                }
 
                                SetAttrs(o,
                                                MUIA_Bitmap_Bitmap, gray_bitmap,
                                                MUIA_Bitmap_SourceColors, colors,
                                                TAG_END);
                        }
                        else
                        {
                                dat->BitMap = bitmap;
                                set(o, MUIA_Bitmap_Bitmap, &dat->BitMap);
                        }
                }
                else
                {
                        if (gray)
                        {
                                FreeBitMap(gray_bitmap);
                        }
                        else if (bitmap.Planes[0])
                        {
                                FreeRaster(bitmap.Planes[0], width, height);
                        }
                }
        }
        else
        {
                o = NULL;
        }
 
        for (k = 0; k < length; ++k)
        {
                if (info[k].glyph)
                {
                        ReleaseInfo(engine,
                                        tag, (IPTR)info[k].glyph,
                                        TAG_END);
                }
        }
 
        FreeVec(info);
 
        CloseEngine(engine);
 
        DEBUG_FONTBITMAP(dprintf("FontBitmap: created object 0x%lx.\n", o));
 
        return (IPTR)o;
}
 
IPTR fbDispose(Class *cl, Object *o)
{
        FontBitmapData *dat = INST_DATA(cl, o);
 
        DEBUG_FONTBITMAP(dprintf("FontBitmap: destroy object 0x%lx.\n", o));
 
        if (dat->GrayBitMap)
        {
                FreeBitMap(dat->GrayBitMap);
        }
        else if (dat->BitMap.Planes[0])
        {
                FreeRaster(dat->BitMap.Planes[0], dat->Width, dat->Height);
        }
 
        return DoSuperMethod(cl, o, OM_DISPOSE);
}
 
AROS_UFH3(ULONG, FontBitmapDispatch,
                AROS_UFHA(Class *, cl, A0),
                AROS_UFHA(Object *, o, A2),
                AROS_UFHA(Msg, msg, A1))
{
        AROS_USERFUNC_INIT
 
        ULONG ret;
 
        switch (msg->MethodID)
        {
                case OM_NEW:
                        ret = fbNew(cl, o, (struct opSet *)msg);
                        break;
 
                case OM_DISPOSE:
                        ret = fbDispose(cl, o);
                        break;
 
                default:
                        ret = DoSuperMethodA(cl, o, msg);
                        break;
        }
 
        return ret;
 
        AROS_USERFUNC_EXIT
}
 
 
void CleanupFontBitmapClass(void)
{
        if (FontBitmapClass)
        {
                MUI_DeleteCustomClass(FontBitmapClass);
                FontBitmapClass = NULL;
        }
}
 
int InitFontBitmapClass(void)
{
        FontBitmapClass = MUI_CreateCustomClass(NULL, MUIC_Bitmap, NULL,
                        sizeof(FontBitmapData), UFHN(FontBitmapDispatch));
        return FontBitmapClass != NULL;
}




↑Jump back a section

Reference

struct GlyphEngine * OpenEngine() ()
void CloseEngine(struct GlyphEngine *ge) (A0)
ULONG SetInfoA(struct GlyphEngine *ge, struct TagItem *tags) (A0,A1)
ULONG ObtainInfoA(struct GlyphEngine *ge, struct TagItem *tags) (A0,A1)
ULONG ReleaseInfoA(struct GlyphEngine *ge, struct TagItem *tags) (A0,A1)

FT_Error FT_Init_FreeType(FT_Library *alibrary)
FT_Error FT_Done_FreeType(FT_Library library)
void FT_Library_Version(FT_Library library, FT_Int *amajor, FT_Int *aminor, FT_Int *apatch)
FT_Error FT_New_Face(FT_Library library, const char *pathname, FT_Long face_index, FT_Face *aface)
FT_Error FT_Done_Face(FT_Face face)
FT_Error FT_New_Memory_Face(FT_Library library, const FT_Byte *file_base, FT_Long file_size, FT_Long face_index, FT_Face *aface)
FT_Error FT_Open_Face(FT_Library library, const FT_Open_Args *args, FT_Long face_index, FT_Face *aface)
FT_Error FT_Attach_File(FT_Face face, const char *filepathname)
FT_Error FT_Attach_Stream(FT_Face face, FT_Open_Args *parameters)
FT_Error FT_Set_Char_Size(FT_Face face, FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt horz_resolution, FT_UInt vert_resolution)
FT_Error FT_Set_Pixel_Sizes(FT_Face face, FT_UInt pixel_width, FT_UInt pixel_height)

void FT_Set_Transform(FT_Face face, FT_Matrix *matrix, FT_Vector *delta)
FT_Error FT_Load_Glyph(FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags)
FT_UInt FT_Get_Char_Index(FT_Face face, FT_ULong charcode)
FT_UInt FT_Get_Name_Index(FT_Face face, FT_String *glyph_name)
FT_Error FT_Load_Char(FT_Face face, FT_ULong char_code, FT_Int32 load_flags)
FT_Error FT_Render_Glyph(FT_GlyphSlot slot, FT_Render_Mode render_mode)
FT_Error FT_Get_Kerning(FT_Face face, FT_UInt left_glyph, FT_UInt right_glyph, FT_UInt kern_mode, FT_Vector *akerning)
FT_Error FT_Get_Glyph_Name(FT_Face face, FT_UInt glyph_index, FT_Pointer buffer, FT_UInt buffer_max)

const char *FT_Get_Postscript_Name(FT_Face face)
FT_Error FT_Select_Charmap(FT_Face face, FT_Encoding encoding)
FT_Error FT_Set_Charmap(FT_Face face, FT_CharMap charmap)
FT_ULong FT_Get_First_Char(FT_Face face, FT_UInt *agindex)
FT_ULong FT_Get_Next_Char(FT_Face face, FT_ULong charcode, FT_UInt *agindex)
FT_Error FT_Get_Glyph(FT_GlyphSlot slot, FT_Glyph *aglyph)
FT_Error FT_Glyph_Copy(FT_Glyph source, FT_Glyph *target)
FT_Error FT_Glyph_Transform(FT_Glyph glyph, FT_Matrix *matrix, FT_Vector *delta)
void FT_Glyph_Get_CBox(FT_Glyph glyph, FT_UInt bbox_mode, FT_BBox *acbox)
FT_Error FT_Glyph_To_Bitmap(FT_Glyph *the_glyph, FT_Render_Mode render_mode, FT_Vector *origin, FT_Bool destroy)

void FT_Done_Glyph(FT_Glyph glyph)
FT_Error FT_New_Size(FT_Face face, FT_Size *asize)
FT_Error FT_Done_Size(FT_Size size)
FT_Error FT_Activate_Size(FT_Size size)
FT_Error FTC_Manager_New(FT_Library library, FT_UInt max_faces, FT_UInt max_sizes, FT_ULong max_bytes, FTC_Face_Requester requester, FT_Pointer req_data, FTC_Manager *amanager)
FT_Error FTC_Manager_Lookup_Face(FTC_Manager manager, FTC_FaceID face_id, FT_Face *aface)
FT_Error FTC_Manager_Lookup_Size(FTC_Manager manager, FTC_Font font, FT_Face *aface, FT_Size *asize)
void FTC_Node_Unref(FTC_Node node, FTC_Manager manager)
FT_Error FTC_ImageCache_New(FTC_Manager manager, FTC_ImageCache *acache)
FT_Error FTC_ImageCache_Lookup(FTC_ImageCache cache, FTC_ImageType type, FT_UInt gindex, FT_Glyph *aglyph, FTC_Node *anode)
FT_Error FTC_SBitCache_New(FTC_Manager manager, FTC_SBitCache *acache)
FT_Error FTC_SBitCache_Lookup(FTC_SBitCache cache, FTC_ImageType type, FT_UInt gindex, FTC_SBit *ansbit, FTC_Node *anode)

void FTC_Manager_Done(FTC_Manager manager)
void FTC_Manager_Reset(FTC_Manager manager)
FT_Error FTC_CMapCache_New(FTC_Manager manager, FTC_CMapCache *acache)
FT_UInt FTC_CMapCache_Lookup(FTC_CMapCache cache, FTC_FaceID face_id, FT_Int cmap_index, FT_UInt32 char_code)

FT_Long FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
FT_Long FT_MulFix(FT_Long a, FT_Long b)
FT_Long FT_DivFix(FT_Long a, FT_Long b)
FT_Fixed FT_RoundFix(FT_Fixed a)
FT_Fixed FT_CeilFix(FT_Fixed a)
FT_Fixed FT_FloorFix(FT_Fixed a)
void FT_Vector_Transform(FT_Vector *vector, const FT_Matrix *matrix)
void FT_Matrix_Multiply(const FT_Matrix *a, FT_Matrix *b)
FT_Error FT_Matrix_Invert(FT_Matrix *matrix)
FT_Fixed FT_Sin(FT_Angle angle)
FT_Fixed FT_Cos(FT_Angle angle)
FT_Fixed FT_Tan(FT_Angle angle)
FT_Angle FT_Atan2(FT_Fixed dx, FT_Fixed dy)
FT_Angle FT_Angle_Diff(FT_Angle angle1, FT_Angle angle2)
void FT_Vector_Unit(FT_Vector *vec, FT_Angle angle)
void FT_Vector_Rotate(FT_Vector *vec, FT_Angle angle)
FT_Fixed FT_Vector_Length(FT_Vector *vec)

# #FT_Vector_Normalize
void FT_Vector_Polarize(FT_Vector *vec, FT_Fixed *length, FT_Angle *angle)
void FT_Vector_From_Polar(FT_Vector *vec, FT_Fixed length, FT_Angle angle)
void FT_List_Add(FT_List list, FT_ListNode node)
void FT_List_Insert(FT_List list, FT_ListNode node)
FT_ListNode FT_List_Find(FT_List list, void *data)
void FT_List_Remove(FT_List list, FT_ListNode node)
void FT_List_Up(FT_List list, FT_ListNode node)
FT_Error FT_List_Iterate(FT_List list, FT_List_Iterator iterator, void *user)
void FT_List_Finalize(FT_List list, FT_List_Destructor destroy, FT_Memory memory, void *user)

FT_Error FT_Outline_New(FT_Library library, FT_UInt numPoints, FT_Int numContours, FT_Outline *anoutline)
FT_Error FT_Outline_New_Internal(FT_Memory memory, FT_UInt numPoints, FT_Int numContours, FT_Outline *anoutline)
FT_Error FT_Outline_Done(FT_Library library, FT_Outline *outline)
FT_Error FT_Outline_Done_Internal(FT_Memory memory, FT_Outline *outline)
FT_Error FT_Outline_Copy(FT_Outline *source, FT_Outline *target)
void FT_Outline_Translate(FT_Outline *outline, FT_Pos xOffset, FT_Pos yOffset)
void FT_Outline_Transform(FT_Outline *outline, FT_Matrix *matrix)
void FT_Outline_Reverse(FT_Outline *outline)
FT_Error FT_Outline_Check(FT_Outline *outline)
void FT_Outline_Get_CBox(FT_Outline *outline, FT_BBox *acbox)
FT_Error FT_Outline_Get_BBox(FT_Outline *outline, FT_BBox *abbox)
FT_Error FT_Outline_Get_Bitmap(FT_Library library, FT_Outline *outline, FT_Bitmap *abitmap)
FT_Error FT_Outline_Render(FT_Library library, FT_Outline *outline, FT_Raster_Params *params)
FT_Error FT_Outline_Decompose(FT_Outline *outline, const FT_Outline_Funcs *func_interface, void *user)

FT_Error FT_Add_Module(FT_Library library, const FT_Module_Class *clazz)
FT_Module FT_Get_Module(FT_Library library, const char *module_name)
FT_Error FT_Remove_Module(FT_Library library, FT_Module module)
FT_Error FT_New_Library(FT_Memory memory, FT_Library *alibrary)
FT_Error FT_Done_Library(FT_Library library)
void FT_Set_Debug_Hook(FT_Library library, FT_UInt hook_index, FT_DebugHook_Func debug_hook)
void FT_Add_Default_Modules(FT_Library library)
FT_Renderer FT_Get_Renderer(FT_Library library, FT_Glyph_Format format)
FT_Error FT_Set_Renderer(FT_Library library, FT_Renderer renderer, FT_UInt num_params, FT_Parameter *parameters)
FT_Error FT_Stream_OpenGzip(FT_Stream stream, FT_Stream source)
void *FT_Get_Sfnt_Table(FT_Face face, FT_Sfnt_Tag tag)
↑Jump back a section
Last modified on 28 September 2012, at 10:16