1 /* Copyright (C) 2001-2019 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13    CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* CID-keyed font utilities */
18 #include "ghost.h"
19 #include "oper.h"
20 #include "gsmatrix.h"
21 #include "gxfcid.h"
22 #include "bfont.h"
23 #include "icid.h"
24 #include "idict.h"
25 #include "idparam.h"
26 #include "ifcid.h"
27 #include "store.h"
28 
29 /* Get the CIDSystemInfo of a CIDFont. */
30 int
cid_font_system_info_param(gs_cid_system_info_t * pcidsi,const ref * prfont)31 cid_font_system_info_param(gs_cid_system_info_t *pcidsi, const ref *prfont)
32 {
33     ref *prcidsi;
34 
35     if (dict_find_string(prfont, "CIDSystemInfo", &prcidsi) <= 0)
36         return_error(gs_error_rangecheck);
37     return cid_system_info_param(pcidsi, prcidsi);
38 }
39 
40 /* Get the additional information for a CIDFontType 0 or 2 CIDFont. */
41 int
cid_font_data_param(os_ptr op,gs_font_cid_data * pdata,ref * pGlyphDirectory)42 cid_font_data_param(os_ptr op, gs_font_cid_data *pdata, ref *pGlyphDirectory)
43 {
44     int code;
45     ref *pgdir;
46 
47     check_type(*op, t_dictionary);
48     if ((code = cid_font_system_info_param(&pdata->CIDSystemInfo, op)) < 0 ||
49         (code = dict_int_param(op, "CIDCount", 0, max_int, -1,
50                                &pdata->CIDCount)) < 0
51         )
52         return code;
53     /* Start by assigning the highest CID to be the count of CIDs. */
54     pdata->MaxCID = pdata->CIDCount + 1;
55     /*
56      * If the font doesn't have a GlyphDirectory, GDBytes is required.
57      * If it does have a GlyphDirectory, GDBytes may still be needed for
58      * CIDMap: it's up to the client to check this.
59      */
60     if (dict_find_string(op, "GlyphDirectory", &pgdir) <= 0) {
61         /* Standard CIDFont, require GDBytes. */
62         make_null(pGlyphDirectory);
63         return dict_int_param(op, "GDBytes", 1, MAX_GDBytes, 0,
64                               &pdata->GDBytes);
65     }
66     if (r_has_type(pgdir, t_dictionary) || r_is_array(pgdir)) {
67         int index;
68         ref element[2];
69 
70         /* GlyphDirectory, GDBytes is optional. */
71         *pGlyphDirectory = *pgdir;
72         code = dict_int_param(op, "GDBytes", 0, MAX_GDBytes, 0,
73                               &pdata->GDBytes);
74 
75         /* If we have a GlyphDirectory then the maximum CID is *not* given by
76          * the number of CIDs in the font. We need to know the maximum CID
77          * when copying fonts, so calculate and store it now.
78          */
79         if (r_has_type(pgdir, t_dictionary)) {
80             index = dict_first(pgdir);
81             while (index >= 0) {
82                 index = dict_next(pgdir, index, (ref *)&element);
83                 if (index >= 0) {
84                     if (element[0].value.intval > pdata->MaxCID)
85                         pdata->MaxCID = element[0].value.intval;
86                 }
87             }
88         }
89         else {
90             pdata->MaxCID = r_size(pgdir) - 1;
91         }
92         return code;
93     } else {
94         return_error(gs_error_typecheck);
95     }
96 }
97