Files
pymol-open-source/layer1/TypeFace.cpp
2024-05-20 09:07:33 -04:00

187 lines
5.0 KiB
C++

/*
A* -------------------------------------------------------------------
B* This file contains source code for the PyMOL computer program
C* copyright 1998-2005 by Warren Lyford Delano of DeLano Scientific.
D* -------------------------------------------------------------------
E* It is unlawful to modify or remove this copyright notice.
F* -------------------------------------------------------------------
G* Please see the accompanying LICENSE file for further information.
H* -------------------------------------------------------------------
I* Additional authors of this source file include:
-*
-*
-*
Z* -------------------------------------------------------------------
*/
#include "MemoryDebug.h"
#include "Base.h"
#include "TypeFace.h"
#ifdef _PYMOL_FREETYPE
#include <ft2build.h>
#include FT_FREETYPE_H
struct _CType {
FT_Library library;
};
struct _CTypeFace {
PyMOLGlobals *G;
FT_Face Face;
float LastSize;
};
int TypeFaceCharacterNew(CTypeFace * I, CharFngrprnt * fprnt, float size)
{
FT_GlyphSlot slot = I->Face->glyph; /* a small shortcut */
if(I->LastSize != size) {
I->LastSize = size;
FT_Set_Char_Size(I->Face, /* handle to face object */
0, /* char_width in 1/64th of points */
(int) (size * 64), /* char_height in 1/64th of points */
72, /* horizontal device resolution */
72); /* vertical device resolution */
}
if(!FT_Load_Char(I->Face, fprnt->u.i.ch, FT_LOAD_RENDER))
return CharacterNewFromBytemap(I->G,
slot->bitmap.width,
slot->bitmap.rows,
-slot->bitmap.pitch,
slot->bitmap.buffer +
((slot->bitmap.rows - 1) * slot->bitmap.pitch),
(float) -slot->bitmap_left,
(float) slot->bitmap.rows - slot->bitmap_top,
slot->advance.x / 64.0F, fprnt);
else
return 0;
}
CTypeFace *TypeFaceLoad(PyMOLGlobals * G, unsigned char *dat, unsigned int len)
{
CType *I = G->Type;
int ok = true;
CTypeFace *result = pymol::calloc<CTypeFace>(1);
if(result) {
FT_Error error = FT_New_Memory_Face(I->library, dat, len, 0, &result->Face);
result->G = G;
if(error)
ok = false;
else {
result->LastSize = 12.0F; /* default size */
error = FT_Set_Char_Size(result->Face, /* handle to face object */
0, /* char_width in 1/64th of points */
(int) (result->LastSize * 64), /* char_height in 1/64th of points */
72, /* horizontal device resolution */
72); /* vertical device resolution */
if(error) {
ok = false;
} else {
error = FT_Select_Charmap(result->Face, FT_ENCODING_UNICODE);
}
}
}
if(!ok) {
FreeP(result);
}
return result;
}
float TypeFaceGetKerning(CTypeFace * I, unsigned int last, unsigned int current,
float size)
{
float result = 0.0F;
FT_UInt glyph_index, previous;
/* FT_Bool use_kerning = FT_HAS_KERNING( I->Face ); */
FT_Bool use_kerning = 1;
if(I->LastSize != size) {
I->LastSize = size;
FT_Set_Char_Size(I->Face, /* handle to face object */
0, /* char_width in 1/64th of points */
(int) (size * 64), /* char_height in 1/64th of points */
72, /* horizontal device resolution */
72); /* vertical device resolution */
}
if(use_kerning) {
previous = FT_Get_Char_Index(I->Face, last);
glyph_index = FT_Get_Char_Index(I->Face, current);
if(previous && glyph_index) {
FT_Vector delta;
FT_Get_Kerning(I->Face, previous, glyph_index, FT_KERNING_DEFAULT, &delta);
result = delta.x / 64.0F;
}
}
return result;
}
void TypeFaceFree(CTypeFace * I)
{
FT_Done_Face(I->Face);
FreeP(I);
}
int TypeInit(PyMOLGlobals * G)
{
CType *I;
if((I = (G->Type = pymol::calloc<CType>(1)))) {
FT_Error error = FT_Init_FreeType(&I->library);
return !error;
}
return 0;
}
void TypeFree(PyMOLGlobals * G)
{
CType *I = G->Type;
FT_Done_FreeType(I->library);
FreeP(G->Type);
}
float TypeFaceGetDescender(CTypeFace * I){
return fabs(I->Face->descender/(float)I->Face->height);
}
#else
int TypeFaceCharacterNew(CTypeFace * I, CharFngrprnt * fprnt, float size)
{
return 0;
}
float TypeFaceGetKerning(CTypeFace * I,
unsigned int last, unsigned int current, float size)
{
return 0.0F;
}
CTypeFace *TypeFaceLoad(PyMOLGlobals * G, unsigned char *dat, unsigned int len)
{
return nullptr;
}
void TypeFaceFree(CTypeFace * face)
{
}
int TypeInit(PyMOLGlobals * G)
{
return 1;
}
void TypeFree(PyMOLGlobals * G)
{
}
float TypeFaceGetDescender(CTypeFace * I){
return 0.f;
}
#endif