/src/mupdf/source/pdf/pdf-metrics.c
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (C) 2004-2021 Artifex Software, Inc. |
2 | | // |
3 | | // This file is part of MuPDF. |
4 | | // |
5 | | // MuPDF is free software: you can redistribute it and/or modify it under the |
6 | | // terms of the GNU Affero General Public License as published by the Free |
7 | | // Software Foundation, either version 3 of the License, or (at your option) |
8 | | // any later version. |
9 | | // |
10 | | // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY |
11 | | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
12 | | // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more |
13 | | // details. |
14 | | // |
15 | | // You should have received a copy of the GNU Affero General Public License |
16 | | // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html> |
17 | | // |
18 | | // Alternative licensing terms are available from the licensor. |
19 | | // For commercial licensing, see <https://www.artifex.com/> or contact |
20 | | // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, |
21 | | // CA 94129, USA, for further information. |
22 | | |
23 | | #include "mupdf/fitz.h" |
24 | | #include "mupdf/pdf.h" |
25 | | |
26 | | #include <stdlib.h> |
27 | | |
28 | | void |
29 | | pdf_set_font_wmode(fz_context *ctx, pdf_font_desc *font, int wmode) |
30 | 2.64k | { |
31 | 2.64k | font->wmode = wmode; |
32 | 2.64k | } |
33 | | |
34 | | void |
35 | | pdf_set_default_hmtx(fz_context *ctx, pdf_font_desc *font, int w) |
36 | 14.1k | { |
37 | 14.1k | font->dhmtx.w = w; |
38 | 14.1k | } |
39 | | |
40 | | void |
41 | | pdf_set_default_vmtx(fz_context *ctx, pdf_font_desc *font, int y, int w) |
42 | 11 | { |
43 | 11 | font->dvmtx.y = y; |
44 | 11 | font->dvmtx.w = w; |
45 | 11 | } |
46 | | |
47 | | void |
48 | | pdf_add_hmtx(fz_context *ctx, pdf_font_desc *font, int lo, int hi, int w) |
49 | 3.36M | { |
50 | 3.36M | if (font->hmtx_len + 1 >= font->hmtx_cap) |
51 | 221k | { |
52 | 221k | int new_cap = font->hmtx_cap + 16; |
53 | 221k | font->hmtx = fz_realloc_array(ctx, font->hmtx, new_cap, pdf_hmtx); |
54 | 221k | font->hmtx_cap = new_cap; |
55 | 221k | } |
56 | | |
57 | 3.36M | font->hmtx[font->hmtx_len].lo = lo; |
58 | 3.36M | font->hmtx[font->hmtx_len].hi = hi; |
59 | 3.36M | font->hmtx[font->hmtx_len].w = w; |
60 | 3.36M | font->hmtx_len++; |
61 | 3.36M | } |
62 | | |
63 | | void |
64 | | pdf_add_vmtx(fz_context *ctx, pdf_font_desc *font, int lo, int hi, int x, int y, int w) |
65 | 0 | { |
66 | 0 | if (font->vmtx_len + 1 >= font->vmtx_cap) |
67 | 0 | { |
68 | 0 | int new_cap = font->vmtx_cap + 16; |
69 | 0 | font->vmtx = fz_realloc_array(ctx, font->vmtx, new_cap, pdf_vmtx); |
70 | 0 | font->vmtx_cap = new_cap; |
71 | 0 | } |
72 | |
|
73 | 0 | font->vmtx[font->vmtx_len].lo = lo; |
74 | 0 | font->vmtx[font->vmtx_len].hi = hi; |
75 | 0 | font->vmtx[font->vmtx_len].x = x; |
76 | 0 | font->vmtx[font->vmtx_len].y = y; |
77 | 0 | font->vmtx[font->vmtx_len].w = w; |
78 | 0 | font->vmtx_len++; |
79 | 0 | } |
80 | | |
81 | | static int cmph(const void *a0, const void *b0) |
82 | 14.8M | { |
83 | 14.8M | pdf_hmtx *a = (pdf_hmtx*)a0; |
84 | 14.8M | pdf_hmtx *b = (pdf_hmtx*)b0; |
85 | 14.8M | return a->lo - b->lo; |
86 | 14.8M | } |
87 | | |
88 | | static int cmpv(const void *a0, const void *b0) |
89 | 0 | { |
90 | 0 | pdf_vmtx *a = (pdf_vmtx*)a0; |
91 | 0 | pdf_vmtx *b = (pdf_vmtx*)b0; |
92 | 0 | return a->lo - b->lo; |
93 | 0 | } |
94 | | |
95 | | void |
96 | | pdf_end_hmtx(fz_context *ctx, pdf_font_desc *font) |
97 | 14.1k | { |
98 | 14.1k | if (!font->hmtx) |
99 | 322 | return; |
100 | 13.8k | qsort(font->hmtx, font->hmtx_len, sizeof(pdf_hmtx), cmph); |
101 | 13.8k | font->size += font->hmtx_cap * sizeof(pdf_hmtx); |
102 | 13.8k | } |
103 | | |
104 | | void |
105 | | pdf_end_vmtx(fz_context *ctx, pdf_font_desc *font) |
106 | 11 | { |
107 | 11 | if (!font->vmtx) |
108 | 11 | return; |
109 | 0 | qsort(font->vmtx, font->vmtx_len, sizeof(pdf_vmtx), cmpv); |
110 | 0 | font->size += font->vmtx_cap * sizeof(pdf_vmtx); |
111 | 0 | } |
112 | | |
113 | | pdf_hmtx |
114 | | pdf_lookup_hmtx(fz_context *ctx, pdf_font_desc *font, int cid) |
115 | 6.98M | { |
116 | 6.98M | int l = 0; |
117 | 6.98M | int r = font->hmtx_len - 1; |
118 | 6.98M | int m; |
119 | | |
120 | 6.98M | if (!font->hmtx) |
121 | 22.1k | goto notfound; |
122 | | |
123 | 47.7M | while (l <= r) |
124 | 47.6M | { |
125 | 47.6M | m = (l + r) >> 1; |
126 | 47.6M | if (cid < font->hmtx[m].lo) |
127 | 22.4M | r = m - 1; |
128 | 25.2M | else if (cid > font->hmtx[m].hi) |
129 | 18.3M | l = m + 1; |
130 | 6.89M | else |
131 | 6.89M | return font->hmtx[m]; |
132 | 47.6M | } |
133 | | |
134 | 89.8k | notfound: |
135 | 89.8k | return font->dhmtx; |
136 | 6.95M | } |
137 | | |
138 | | pdf_vmtx |
139 | | pdf_lookup_vmtx(fz_context *ctx, pdf_font_desc *font, int cid) |
140 | 405 | { |
141 | 405 | pdf_hmtx h; |
142 | 405 | pdf_vmtx v; |
143 | 405 | int l = 0; |
144 | 405 | int r = font->vmtx_len - 1; |
145 | 405 | int m; |
146 | | |
147 | 405 | if (!font->vmtx) |
148 | 405 | goto notfound; |
149 | | |
150 | 0 | while (l <= r) |
151 | 0 | { |
152 | 0 | m = (l + r) >> 1; |
153 | 0 | if (cid < font->vmtx[m].lo) |
154 | 0 | r = m - 1; |
155 | 0 | else if (cid > font->vmtx[m].hi) |
156 | 0 | l = m + 1; |
157 | 0 | else |
158 | 0 | return font->vmtx[m]; |
159 | 0 | } |
160 | | |
161 | 405 | notfound: |
162 | 405 | h = pdf_lookup_hmtx(ctx, font, cid); |
163 | 405 | v = font->dvmtx; |
164 | 405 | v.x = h.w / 2; |
165 | 405 | return v; |
166 | 0 | } |