1 | /**************************************************************************** |
2 | * |
3 | * pfrdrivr.c |
4 | * |
5 | * FreeType PFR driver interface (body). |
6 | * |
7 | * Copyright (C) 2002-2023 by |
8 | * David Turner, Robert Wilhelm, and Werner Lemberg. |
9 | * |
10 | * This file is part of the FreeType project, and may only be used, |
11 | * modified, and distributed under the terms of the FreeType project |
12 | * license, LICENSE.TXT. By continuing to use, modify, or distribute |
13 | * this file you indicate that you have read the license and |
14 | * understand and accept it fully. |
15 | * |
16 | */ |
17 | |
18 | |
19 | #include <freetype/internal/ftdebug.h> |
20 | #include <freetype/internal/ftstream.h> |
21 | #include <freetype/internal/services/svpfr.h> |
22 | #include <freetype/internal/services/svfntfmt.h> |
23 | #include "pfrdrivr.h" |
24 | #include "pfrobjs.h" |
25 | |
26 | #include "pfrerror.h" |
27 | |
28 | |
29 | FT_CALLBACK_DEF( FT_Error ) |
30 | pfr_get_kerning( FT_Face face, /* PFR_Face */ |
31 | FT_UInt left, |
32 | FT_UInt right, |
33 | FT_Vector *avector ) |
34 | { |
35 | PFR_Face pfrface = (PFR_Face)face; |
36 | PFR_PhyFont phys = &pfrface->phy_font; |
37 | |
38 | |
39 | (void)pfr_face_get_kerning( face, left, right, avector ); |
40 | |
41 | /* convert from metrics to outline units when necessary */ |
42 | if ( phys->outline_resolution != phys->metrics_resolution ) |
43 | { |
44 | if ( avector->x != 0 ) |
45 | avector->x = FT_MulDiv( avector->x, |
46 | (FT_Long)phys->outline_resolution, |
47 | (FT_Long)phys->metrics_resolution ); |
48 | |
49 | if ( avector->y != 0 ) |
50 | avector->y = FT_MulDiv( avector->y, |
51 | (FT_Long)phys->outline_resolution, |
52 | (FT_Long)phys->metrics_resolution ); |
53 | } |
54 | |
55 | return FT_Err_Ok; |
56 | } |
57 | |
58 | |
59 | /* |
60 | * PFR METRICS SERVICE |
61 | * |
62 | */ |
63 | |
64 | FT_CALLBACK_DEF( FT_Error ) |
65 | pfr_get_advance( FT_Face face, /* PFR_Face */ |
66 | FT_UInt gindex, |
67 | FT_Pos *anadvance ) |
68 | { |
69 | PFR_Face pfrface = (PFR_Face)face; |
70 | FT_Error error = FT_ERR( Invalid_Argument ); |
71 | |
72 | |
73 | *anadvance = 0; |
74 | |
75 | if ( !gindex ) |
76 | goto Exit; |
77 | |
78 | gindex--; |
79 | |
80 | if ( pfrface ) |
81 | { |
82 | PFR_PhyFont phys = &pfrface->phy_font; |
83 | |
84 | |
85 | if ( gindex < phys->num_chars ) |
86 | { |
87 | *anadvance = phys->chars[gindex].advance; |
88 | error = FT_Err_Ok; |
89 | } |
90 | } |
91 | |
92 | Exit: |
93 | return error; |
94 | } |
95 | |
96 | |
97 | FT_CALLBACK_DEF( FT_Error ) |
98 | pfr_get_metrics( FT_Face face, /* PFR_Face */ |
99 | FT_UInt *anoutline_resolution, |
100 | FT_UInt *ametrics_resolution, |
101 | FT_Fixed *ametrics_x_scale, |
102 | FT_Fixed *ametrics_y_scale ) |
103 | { |
104 | PFR_Face pfrface = (PFR_Face)face; |
105 | PFR_PhyFont phys = &pfrface->phy_font; |
106 | FT_Fixed x_scale, y_scale; |
107 | FT_Size size = pfrface->root.size; |
108 | |
109 | |
110 | if ( anoutline_resolution ) |
111 | *anoutline_resolution = phys->outline_resolution; |
112 | |
113 | if ( ametrics_resolution ) |
114 | *ametrics_resolution = phys->metrics_resolution; |
115 | |
116 | x_scale = 0x10000L; |
117 | y_scale = 0x10000L; |
118 | |
119 | if ( size ) |
120 | { |
121 | x_scale = FT_DivFix( size->metrics.x_ppem << 6, |
122 | (FT_Long)phys->metrics_resolution ); |
123 | |
124 | y_scale = FT_DivFix( size->metrics.y_ppem << 6, |
125 | (FT_Long)phys->metrics_resolution ); |
126 | } |
127 | |
128 | if ( ametrics_x_scale ) |
129 | *ametrics_x_scale = x_scale; |
130 | |
131 | if ( ametrics_y_scale ) |
132 | *ametrics_y_scale = y_scale; |
133 | |
134 | return FT_Err_Ok; |
135 | } |
136 | |
137 | |
138 | static |
139 | const FT_Service_PfrMetricsRec pfr_metrics_service_rec = |
140 | { |
141 | pfr_get_metrics, /* get_metrics */ |
142 | pfr_face_get_kerning, /* get_kerning */ |
143 | pfr_get_advance /* get_advance */ |
144 | }; |
145 | |
146 | |
147 | /* |
148 | * SERVICE LIST |
149 | * |
150 | */ |
151 | |
152 | static const FT_ServiceDescRec pfr_services[] = |
153 | { |
154 | { FT_SERVICE_ID_PFR_METRICS, &pfr_metrics_service_rec }, |
155 | { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_PFR }, |
156 | { NULL, NULL } |
157 | }; |
158 | |
159 | |
160 | FT_CALLBACK_DEF( FT_Module_Interface ) |
161 | pfr_get_service( FT_Module module, |
162 | const FT_String* service_id ) |
163 | { |
164 | FT_UNUSED( module ); |
165 | |
166 | return ft_service_list_lookup( pfr_services, service_id ); |
167 | } |
168 | |
169 | |
170 | FT_CALLBACK_TABLE_DEF |
171 | const FT_Driver_ClassRec pfr_driver_class = |
172 | { |
173 | { |
174 | FT_MODULE_FONT_DRIVER | |
175 | FT_MODULE_DRIVER_SCALABLE, |
176 | |
177 | sizeof ( FT_DriverRec ), |
178 | |
179 | "pfr" , |
180 | 0x10000L, |
181 | 0x20000L, |
182 | |
183 | NULL, /* module-specific interface */ |
184 | |
185 | NULL, /* FT_Module_Constructor module_init */ |
186 | NULL, /* FT_Module_Destructor module_done */ |
187 | pfr_get_service /* FT_Module_Requester get_interface */ |
188 | }, |
189 | |
190 | sizeof ( PFR_FaceRec ), |
191 | sizeof ( PFR_SizeRec ), |
192 | sizeof ( PFR_SlotRec ), |
193 | |
194 | pfr_face_init, /* FT_Face_InitFunc init_face */ |
195 | pfr_face_done, /* FT_Face_DoneFunc done_face */ |
196 | NULL, /* FT_Size_InitFunc init_size */ |
197 | NULL, /* FT_Size_DoneFunc done_size */ |
198 | pfr_slot_init, /* FT_Slot_InitFunc init_slot */ |
199 | pfr_slot_done, /* FT_Slot_DoneFunc done_slot */ |
200 | |
201 | pfr_slot_load, /* FT_Slot_LoadFunc load_glyph */ |
202 | |
203 | pfr_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ |
204 | NULL, /* FT_Face_AttachFunc attach_file */ |
205 | NULL, /* FT_Face_GetAdvancesFunc get_advances */ |
206 | |
207 | NULL, /* FT_Size_RequestFunc request_size */ |
208 | NULL, /* FT_Size_SelectFunc select_size */ |
209 | }; |
210 | |
211 | |
212 | /* END */ |
213 | |