1 /****************************************************************************
2  *
3  * ftpfr.c
4  *
5  *   FreeType API for accessing PFR-specific data (body).
6  *
7  * Copyright (C) 2002-2020 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 #include <freetype/internal/ftdebug.h>
19 
20 #include <freetype/internal/ftobjs.h>
21 #include <freetype/internal/services/svpfr.h>
22 
23 
24   /* check the format */
25   static FT_Service_PfrMetrics
ft_pfr_check(FT_Face face)26   ft_pfr_check( FT_Face  face )
27   {
28     FT_Service_PfrMetrics  service = NULL;
29 
30 
31     if ( face )
32       FT_FACE_LOOKUP_SERVICE( face, service, PFR_METRICS );
33 
34     return service;
35   }
36 
37 
38   /* documentation is in ftpfr.h */
39 
40   FT_EXPORT_DEF( FT_Error )
FT_Get_PFR_Metrics(FT_Face face,FT_UInt * aoutline_resolution,FT_UInt * ametrics_resolution,FT_Fixed * ametrics_x_scale,FT_Fixed * ametrics_y_scale)41   FT_Get_PFR_Metrics( FT_Face    face,
42                       FT_UInt   *aoutline_resolution,
43                       FT_UInt   *ametrics_resolution,
44                       FT_Fixed  *ametrics_x_scale,
45                       FT_Fixed  *ametrics_y_scale )
46   {
47     FT_Error               error = FT_Err_Ok;
48     FT_Service_PfrMetrics  service;
49 
50 
51     if ( !face )
52       return FT_THROW( Invalid_Face_Handle );
53 
54     service = ft_pfr_check( face );
55     if ( service )
56     {
57       error = service->get_metrics( face,
58                                     aoutline_resolution,
59                                     ametrics_resolution,
60                                     ametrics_x_scale,
61                                     ametrics_y_scale );
62     }
63     else
64     {
65       FT_Fixed  x_scale, y_scale;
66 
67 
68       /* this is not a PFR font */
69       if ( aoutline_resolution )
70         *aoutline_resolution = face->units_per_EM;
71 
72       if ( ametrics_resolution )
73         *ametrics_resolution = face->units_per_EM;
74 
75       x_scale = y_scale = 0x10000L;
76       if ( face->size )
77       {
78         x_scale = face->size->metrics.x_scale;
79         y_scale = face->size->metrics.y_scale;
80       }
81 
82       if ( ametrics_x_scale )
83         *ametrics_x_scale = x_scale;
84 
85       if ( ametrics_y_scale )
86         *ametrics_y_scale = y_scale;
87 
88       error = FT_THROW( Unknown_File_Format );
89     }
90 
91     return error;
92   }
93 
94 
95   /* documentation is in ftpfr.h */
96 
97   FT_EXPORT_DEF( FT_Error )
FT_Get_PFR_Kerning(FT_Face face,FT_UInt left,FT_UInt right,FT_Vector * avector)98   FT_Get_PFR_Kerning( FT_Face     face,
99                       FT_UInt     left,
100                       FT_UInt     right,
101                       FT_Vector  *avector )
102   {
103     FT_Error               error;
104     FT_Service_PfrMetrics  service;
105 
106 
107     if ( !face )
108       return FT_THROW( Invalid_Face_Handle );
109 
110     if ( !avector )
111       return FT_THROW( Invalid_Argument );
112 
113     service = ft_pfr_check( face );
114     if ( service )
115       error = service->get_kerning( face, left, right, avector );
116     else
117       error = FT_Get_Kerning( face, left, right,
118                               FT_KERNING_UNSCALED, avector );
119 
120     return error;
121   }
122 
123 
124   /* documentation is in ftpfr.h */
125 
126   FT_EXPORT_DEF( FT_Error )
FT_Get_PFR_Advance(FT_Face face,FT_UInt gindex,FT_Pos * aadvance)127   FT_Get_PFR_Advance( FT_Face   face,
128                       FT_UInt   gindex,
129                       FT_Pos   *aadvance )
130   {
131     FT_Error               error;
132     FT_Service_PfrMetrics  service;
133 
134 
135     if ( !face )
136       return FT_THROW( Invalid_Face_Handle );
137 
138     if ( !aadvance )
139       return FT_THROW( Invalid_Argument );
140 
141     service = ft_pfr_check( face );
142     if ( service )
143       error = service->get_advance( face, gindex, aadvance );
144     else
145       /* XXX: TODO: PROVIDE ADVANCE-LOADING METHOD TO ALL FONT DRIVERS */
146       error = FT_THROW( Invalid_Argument );
147 
148     return error;
149   }
150 
151 
152 /* END */
153