Aros/开发人员/文档/库/FreeType2
外观
为Aros提供TrueType、OpenType和Type 1字体和字形支持。
链接 -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;
}
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)