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