1 #include "mupdf/fitz.h"
2 #include "mupdf/pdf.h"
3 
4 #include <stdlib.h>
5 
6 void
pdf_set_font_wmode(fz_context * ctx,pdf_font_desc * font,int wmode)7 pdf_set_font_wmode(fz_context *ctx, pdf_font_desc *font, int wmode)
8 {
9 	font->wmode = wmode;
10 }
11 
12 void
pdf_set_default_hmtx(fz_context * ctx,pdf_font_desc * font,int w)13 pdf_set_default_hmtx(fz_context *ctx, pdf_font_desc *font, int w)
14 {
15 	font->dhmtx.w = w;
16 }
17 
18 void
pdf_set_default_vmtx(fz_context * ctx,pdf_font_desc * font,int y,int w)19 pdf_set_default_vmtx(fz_context *ctx, pdf_font_desc *font, int y, int w)
20 {
21 	font->dvmtx.y = y;
22 	font->dvmtx.w = w;
23 }
24 
25 void
pdf_add_hmtx(fz_context * ctx,pdf_font_desc * font,int lo,int hi,int w)26 pdf_add_hmtx(fz_context *ctx, pdf_font_desc *font, int lo, int hi, int w)
27 {
28 	if (font->hmtx_len + 1 >= font->hmtx_cap)
29 	{
30 		int new_cap = font->hmtx_cap + 16;
31 		font->hmtx = fz_realloc_array(ctx, font->hmtx, new_cap, pdf_hmtx);
32 		font->hmtx_cap = new_cap;
33 	}
34 
35 	font->hmtx[font->hmtx_len].lo = lo;
36 	font->hmtx[font->hmtx_len].hi = hi;
37 	font->hmtx[font->hmtx_len].w = w;
38 	font->hmtx_len++;
39 }
40 
41 void
pdf_add_vmtx(fz_context * ctx,pdf_font_desc * font,int lo,int hi,int x,int y,int w)42 pdf_add_vmtx(fz_context *ctx, pdf_font_desc *font, int lo, int hi, int x, int y, int w)
43 {
44 	if (font->vmtx_len + 1 >= font->vmtx_cap)
45 	{
46 		int new_cap = font->vmtx_cap + 16;
47 		font->vmtx = fz_realloc_array(ctx, font->vmtx, new_cap, pdf_vmtx);
48 		font->vmtx_cap = new_cap;
49 	}
50 
51 	font->vmtx[font->vmtx_len].lo = lo;
52 	font->vmtx[font->vmtx_len].hi = hi;
53 	font->vmtx[font->vmtx_len].x = x;
54 	font->vmtx[font->vmtx_len].y = y;
55 	font->vmtx[font->vmtx_len].w = w;
56 	font->vmtx_len++;
57 }
58 
cmph(const void * a0,const void * b0)59 static int cmph(const void *a0, const void *b0)
60 {
61 	pdf_hmtx *a = (pdf_hmtx*)a0;
62 	pdf_hmtx *b = (pdf_hmtx*)b0;
63 	return a->lo - b->lo;
64 }
65 
cmpv(const void * a0,const void * b0)66 static int cmpv(const void *a0, const void *b0)
67 {
68 	pdf_vmtx *a = (pdf_vmtx*)a0;
69 	pdf_vmtx *b = (pdf_vmtx*)b0;
70 	return a->lo - b->lo;
71 }
72 
73 void
pdf_end_hmtx(fz_context * ctx,pdf_font_desc * font)74 pdf_end_hmtx(fz_context *ctx, pdf_font_desc *font)
75 {
76 	if (!font->hmtx)
77 		return;
78 	qsort(font->hmtx, font->hmtx_len, sizeof(pdf_hmtx), cmph);
79 	font->size += font->hmtx_cap * sizeof(pdf_hmtx);
80 }
81 
82 void
pdf_end_vmtx(fz_context * ctx,pdf_font_desc * font)83 pdf_end_vmtx(fz_context *ctx, pdf_font_desc *font)
84 {
85 	if (!font->vmtx)
86 		return;
87 	qsort(font->vmtx, font->vmtx_len, sizeof(pdf_vmtx), cmpv);
88 	font->size += font->vmtx_cap * sizeof(pdf_vmtx);
89 }
90 
91 pdf_hmtx
pdf_lookup_hmtx(fz_context * ctx,pdf_font_desc * font,int cid)92 pdf_lookup_hmtx(fz_context *ctx, pdf_font_desc *font, int cid)
93 {
94 	int l = 0;
95 	int r = font->hmtx_len - 1;
96 	int m;
97 
98 	if (!font->hmtx)
99 		goto notfound;
100 
101 	while (l <= r)
102 	{
103 		m = (l + r) >> 1;
104 		if (cid < font->hmtx[m].lo)
105 			r = m - 1;
106 		else if (cid > font->hmtx[m].hi)
107 			l = m + 1;
108 		else
109 			return font->hmtx[m];
110 	}
111 
112 notfound:
113 	return font->dhmtx;
114 }
115 
116 pdf_vmtx
pdf_lookup_vmtx(fz_context * ctx,pdf_font_desc * font,int cid)117 pdf_lookup_vmtx(fz_context *ctx, pdf_font_desc *font, int cid)
118 {
119 	pdf_hmtx h;
120 	pdf_vmtx v;
121 	int l = 0;
122 	int r = font->vmtx_len - 1;
123 	int m;
124 
125 	if (!font->vmtx)
126 		goto notfound;
127 
128 	while (l <= r)
129 	{
130 		m = (l + r) >> 1;
131 		if (cid < font->vmtx[m].lo)
132 			r = m - 1;
133 		else if (cid > font->vmtx[m].hi)
134 			l = m + 1;
135 		else
136 			return font->vmtx[m];
137 	}
138 
139 notfound:
140 	h = pdf_lookup_hmtx(ctx, font, cid);
141 	v = font->dvmtx;
142 	v.x = h.w / 2;
143 	return v;
144 }
145