Path: blob/master/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftserv.h
42819 views
/****************************************************************************1*2* ftserv.h3*4* The FreeType services (specification only).5*6* Copyright (C) 2003-2020 by7* David Turner, Robert Wilhelm, and Werner Lemberg.8*9* This file is part of the FreeType project, and may only be used,10* modified, and distributed under the terms of the FreeType project11* license, LICENSE.TXT. By continuing to use, modify, or distribute12* this file you indicate that you have read the license and13* understand and accept it fully.14*15*/1617/**************************************************************************18*19* Each module can export one or more 'services'. Each service is20* identified by a constant string and modeled by a pointer; the latter21* generally corresponds to a structure containing function pointers.22*23* Note that a service's data cannot be a mere function pointer because in24* C it is possible that function pointers might be implemented differently25* than data pointers (e.g. 48 bits instead of 32).26*27*/282930#ifndef FTSERV_H_31#define FTSERV_H_3233#include "compiler-macros.h"3435FT_BEGIN_HEADER3637/**************************************************************************38*39* @macro:40* FT_FACE_FIND_SERVICE41*42* @description:43* This macro is used to look up a service from a face's driver module.44*45* @input:46* face ::47* The source face handle.48*49* id ::50* A string describing the service as defined in the service's header51* files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to52* 'multi-masters'). It is automatically prefixed with53* `FT_SERVICE_ID_`.54*55* @output:56* ptr ::57* A variable that receives the service pointer. Will be `NULL` if not58* found.59*/60#ifdef __cplusplus6162#define FT_FACE_FIND_SERVICE( face, ptr, id ) \63FT_BEGIN_STMNT \64FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \65FT_Pointer _tmp_ = NULL; \66FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \67\68\69if ( module->clazz->get_interface ) \70_tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \71*_pptr_ = _tmp_; \72FT_END_STMNT7374#else /* !C++ */7576#define FT_FACE_FIND_SERVICE( face, ptr, id ) \77FT_BEGIN_STMNT \78FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \79FT_Pointer _tmp_ = NULL; \80\81if ( module->clazz->get_interface ) \82_tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \83ptr = _tmp_; \84FT_END_STMNT8586#endif /* !C++ */878889/**************************************************************************90*91* @macro:92* FT_FACE_FIND_GLOBAL_SERVICE93*94* @description:95* This macro is used to look up a service from all modules.96*97* @input:98* face ::99* The source face handle.100*101* id ::102* A string describing the service as defined in the service's header103* files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to104* 'multi-masters'). It is automatically prefixed with105* `FT_SERVICE_ID_`.106*107* @output:108* ptr ::109* A variable that receives the service pointer. Will be `NULL` if not110* found.111*/112#ifdef __cplusplus113114#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \115FT_BEGIN_STMNT \116FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \117FT_Pointer _tmp_; \118FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \119\120\121_tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \122*_pptr_ = _tmp_; \123FT_END_STMNT124125#else /* !C++ */126127#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \128FT_BEGIN_STMNT \129FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \130FT_Pointer _tmp_; \131\132\133_tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \134ptr = _tmp_; \135FT_END_STMNT136137#endif /* !C++ */138139140/*************************************************************************/141/*************************************************************************/142/***** *****/143/***** S E R V I C E D E S C R I P T O R S *****/144/***** *****/145/*************************************************************************/146/*************************************************************************/147148/*149* The following structure is used to _describe_ a given service to the150* library. This is useful to build simple static service lists.151*/152typedef struct FT_ServiceDescRec_153{154const char* serv_id; /* service name */155const void* serv_data; /* service pointer/data */156157} FT_ServiceDescRec;158159typedef const FT_ServiceDescRec* FT_ServiceDesc;160161162/**************************************************************************163*164* @macro:165* FT_DEFINE_SERVICEDESCREC1166* FT_DEFINE_SERVICEDESCREC2167* FT_DEFINE_SERVICEDESCREC3168* FT_DEFINE_SERVICEDESCREC4169* FT_DEFINE_SERVICEDESCREC5170* FT_DEFINE_SERVICEDESCREC6171* FT_DEFINE_SERVICEDESCREC7172* FT_DEFINE_SERVICEDESCREC8173* FT_DEFINE_SERVICEDESCREC9174* FT_DEFINE_SERVICEDESCREC10175*176* @description:177* Used to initialize an array of FT_ServiceDescRec structures.178*179* The array will be allocated in the global scope (or the scope where180* the macro is used).181*/182#define FT_DEFINE_SERVICEDESCREC1( class_, \183serv_id_1, serv_data_1 ) \184static const FT_ServiceDescRec class_[] = \185{ \186{ serv_id_1, serv_data_1 }, \187{ NULL, NULL } \188};189190#define FT_DEFINE_SERVICEDESCREC2( class_, \191serv_id_1, serv_data_1, \192serv_id_2, serv_data_2 ) \193static const FT_ServiceDescRec class_[] = \194{ \195{ serv_id_1, serv_data_1 }, \196{ serv_id_2, serv_data_2 }, \197{ NULL, NULL } \198};199200#define FT_DEFINE_SERVICEDESCREC3( class_, \201serv_id_1, serv_data_1, \202serv_id_2, serv_data_2, \203serv_id_3, serv_data_3 ) \204static const FT_ServiceDescRec class_[] = \205{ \206{ serv_id_1, serv_data_1 }, \207{ serv_id_2, serv_data_2 }, \208{ serv_id_3, serv_data_3 }, \209{ NULL, NULL } \210};211212#define FT_DEFINE_SERVICEDESCREC4( class_, \213serv_id_1, serv_data_1, \214serv_id_2, serv_data_2, \215serv_id_3, serv_data_3, \216serv_id_4, serv_data_4 ) \217static const FT_ServiceDescRec class_[] = \218{ \219{ serv_id_1, serv_data_1 }, \220{ serv_id_2, serv_data_2 }, \221{ serv_id_3, serv_data_3 }, \222{ serv_id_4, serv_data_4 }, \223{ NULL, NULL } \224};225226#define FT_DEFINE_SERVICEDESCREC5( class_, \227serv_id_1, serv_data_1, \228serv_id_2, serv_data_2, \229serv_id_3, serv_data_3, \230serv_id_4, serv_data_4, \231serv_id_5, serv_data_5 ) \232static const FT_ServiceDescRec class_[] = \233{ \234{ serv_id_1, serv_data_1 }, \235{ serv_id_2, serv_data_2 }, \236{ serv_id_3, serv_data_3 }, \237{ serv_id_4, serv_data_4 }, \238{ serv_id_5, serv_data_5 }, \239{ NULL, NULL } \240};241242#define FT_DEFINE_SERVICEDESCREC6( class_, \243serv_id_1, serv_data_1, \244serv_id_2, serv_data_2, \245serv_id_3, serv_data_3, \246serv_id_4, serv_data_4, \247serv_id_5, serv_data_5, \248serv_id_6, serv_data_6 ) \249static const FT_ServiceDescRec class_[] = \250{ \251{ serv_id_1, serv_data_1 }, \252{ serv_id_2, serv_data_2 }, \253{ serv_id_3, serv_data_3 }, \254{ serv_id_4, serv_data_4 }, \255{ serv_id_5, serv_data_5 }, \256{ serv_id_6, serv_data_6 }, \257{ NULL, NULL } \258};259260#define FT_DEFINE_SERVICEDESCREC7( class_, \261serv_id_1, serv_data_1, \262serv_id_2, serv_data_2, \263serv_id_3, serv_data_3, \264serv_id_4, serv_data_4, \265serv_id_5, serv_data_5, \266serv_id_6, serv_data_6, \267serv_id_7, serv_data_7 ) \268static const FT_ServiceDescRec class_[] = \269{ \270{ serv_id_1, serv_data_1 }, \271{ serv_id_2, serv_data_2 }, \272{ serv_id_3, serv_data_3 }, \273{ serv_id_4, serv_data_4 }, \274{ serv_id_5, serv_data_5 }, \275{ serv_id_6, serv_data_6 }, \276{ serv_id_7, serv_data_7 }, \277{ NULL, NULL } \278};279280#define FT_DEFINE_SERVICEDESCREC8( class_, \281serv_id_1, serv_data_1, \282serv_id_2, serv_data_2, \283serv_id_3, serv_data_3, \284serv_id_4, serv_data_4, \285serv_id_5, serv_data_5, \286serv_id_6, serv_data_6, \287serv_id_7, serv_data_7, \288serv_id_8, serv_data_8 ) \289static const FT_ServiceDescRec class_[] = \290{ \291{ serv_id_1, serv_data_1 }, \292{ serv_id_2, serv_data_2 }, \293{ serv_id_3, serv_data_3 }, \294{ serv_id_4, serv_data_4 }, \295{ serv_id_5, serv_data_5 }, \296{ serv_id_6, serv_data_6 }, \297{ serv_id_7, serv_data_7 }, \298{ serv_id_8, serv_data_8 }, \299{ NULL, NULL } \300};301302#define FT_DEFINE_SERVICEDESCREC9( class_, \303serv_id_1, serv_data_1, \304serv_id_2, serv_data_2, \305serv_id_3, serv_data_3, \306serv_id_4, serv_data_4, \307serv_id_5, serv_data_5, \308serv_id_6, serv_data_6, \309serv_id_7, serv_data_7, \310serv_id_8, serv_data_8, \311serv_id_9, serv_data_9 ) \312static const FT_ServiceDescRec class_[] = \313{ \314{ serv_id_1, serv_data_1 }, \315{ serv_id_2, serv_data_2 }, \316{ serv_id_3, serv_data_3 }, \317{ serv_id_4, serv_data_4 }, \318{ serv_id_5, serv_data_5 }, \319{ serv_id_6, serv_data_6 }, \320{ serv_id_7, serv_data_7 }, \321{ serv_id_8, serv_data_8 }, \322{ serv_id_9, serv_data_9 }, \323{ NULL, NULL } \324};325326#define FT_DEFINE_SERVICEDESCREC10( class_, \327serv_id_1, serv_data_1, \328serv_id_2, serv_data_2, \329serv_id_3, serv_data_3, \330serv_id_4, serv_data_4, \331serv_id_5, serv_data_5, \332serv_id_6, serv_data_6, \333serv_id_7, serv_data_7, \334serv_id_8, serv_data_8, \335serv_id_9, serv_data_9, \336serv_id_10, serv_data_10 ) \337static const FT_ServiceDescRec class_[] = \338{ \339{ serv_id_1, serv_data_1 }, \340{ serv_id_2, serv_data_2 }, \341{ serv_id_3, serv_data_3 }, \342{ serv_id_4, serv_data_4 }, \343{ serv_id_5, serv_data_5 }, \344{ serv_id_6, serv_data_6 }, \345{ serv_id_7, serv_data_7 }, \346{ serv_id_8, serv_data_8 }, \347{ serv_id_9, serv_data_9 }, \348{ serv_id_10, serv_data_10 }, \349{ NULL, NULL } \350};351352353/*354* Parse a list of FT_ServiceDescRec descriptors and look for a specific355* service by ID. Note that the last element in the array must be { NULL,356* NULL }, and that the function should return NULL if the service isn't357* available.358*359* This function can be used by modules to implement their `get_service'360* method.361*/362FT_BASE( FT_Pointer )363ft_service_list_lookup( FT_ServiceDesc service_descriptors,364const char* service_id );365366367/*************************************************************************/368/*************************************************************************/369/***** *****/370/***** S E R V I C E S C A C H E *****/371/***** *****/372/*************************************************************************/373/*************************************************************************/374375/*376* This structure is used to store a cache for several frequently used377* services. It is the type of `face->internal->services'. You should378* only use FT_FACE_LOOKUP_SERVICE to access it.379*380* All fields should have the type FT_Pointer to relax compilation381* dependencies. We assume the developer isn't completely stupid.382*383* Each field must be named `service_XXXX' where `XXX' corresponds to the384* correct FT_SERVICE_ID_XXXX macro. See the definition of385* FT_FACE_LOOKUP_SERVICE below how this is implemented.386*387*/388typedef struct FT_ServiceCacheRec_389{390FT_Pointer service_POSTSCRIPT_FONT_NAME;391FT_Pointer service_MULTI_MASTERS;392FT_Pointer service_METRICS_VARIATIONS;393FT_Pointer service_GLYPH_DICT;394FT_Pointer service_PFR_METRICS;395FT_Pointer service_WINFNT;396397} FT_ServiceCacheRec, *FT_ServiceCache;398399400/*401* A magic number used within the services cache.402*/403404/* ensure that value `1' has the same width as a pointer */405#define FT_SERVICE_UNAVAILABLE ((FT_Pointer)~(FT_PtrDist)1)406407408/**************************************************************************409*410* @macro:411* FT_FACE_LOOKUP_SERVICE412*413* @description:414* This macro is used to look up a service from a face's driver module415* using its cache.416*417* @input:418* face ::419* The source face handle containing the cache.420*421* field ::422* The field name in the cache.423*424* id ::425* The service ID.426*427* @output:428* ptr ::429* A variable receiving the service data. `NULL` if not available.430*/431#ifdef __cplusplus432433#define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \434FT_BEGIN_STMNT \435FT_Pointer svc; \436FT_Pointer* Pptr = (FT_Pointer*)&(ptr); \437\438\439svc = FT_FACE( face )->internal->services. service_ ## id; \440if ( svc == FT_SERVICE_UNAVAILABLE ) \441svc = NULL; \442else if ( svc == NULL ) \443{ \444FT_FACE_FIND_SERVICE( face, svc, id ); \445\446FT_FACE( face )->internal->services. service_ ## id = \447(FT_Pointer)( svc != NULL ? svc \448: FT_SERVICE_UNAVAILABLE ); \449} \450*Pptr = svc; \451FT_END_STMNT452453#else /* !C++ */454455#define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \456FT_BEGIN_STMNT \457FT_Pointer svc; \458\459\460svc = FT_FACE( face )->internal->services. service_ ## id; \461if ( svc == FT_SERVICE_UNAVAILABLE ) \462svc = NULL; \463else if ( svc == NULL ) \464{ \465FT_FACE_FIND_SERVICE( face, svc, id ); \466\467FT_FACE( face )->internal->services. service_ ## id = \468(FT_Pointer)( svc != NULL ? svc \469: FT_SERVICE_UNAVAILABLE ); \470} \471ptr = svc; \472FT_END_STMNT473474#endif /* !C++ */475476/*477* A macro used to define new service structure types.478*/479480#define FT_DEFINE_SERVICE( name ) \481typedef struct FT_Service_ ## name ## Rec_ \482FT_Service_ ## name ## Rec ; \483typedef struct FT_Service_ ## name ## Rec_ \484const * FT_Service_ ## name ; \485struct FT_Service_ ## name ## Rec_486487/* */488489FT_END_HEADER490491#endif /* FTSERV_H_ */492493494/* END */495496497