Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/workdir/UnpackedTarball/harfbuzz/src/hb-subset-table-cff.cc
Line
Count
Source
1
#include "hb-subset-table.hh"
2
3
#include "hb-ot-cff1-table.hh"
4
#include "hb-ot-cff2-table.hh"
5
#include "hb-ot-vorg-table.hh"
6
7
8
#ifndef HB_NO_SUBSET_CFF
9
template<>
10
struct hb_subset_plan_t::source_table_loader<const OT::cff1>
11
{
12
  auto operator () (hb_subset_plan_t *plan)
13
  HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff1_accel :
14
      plan->inprogress_accelerator ? plan->inprogress_accelerator->cff1_accel :
15
      plan->cff1_accel)
16
};
17
template<>
18
struct hb_subset_plan_t::source_table_loader<const OT::cff2>
19
{
20
  auto operator () (hb_subset_plan_t *plan)
21
  HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff2_accel :
22
      plan->inprogress_accelerator ? plan->inprogress_accelerator->cff2_accel :
23
      plan->cff2_accel)
24
};
25
#endif
26
27
28
bool _hb_subset_table_cff   (hb_subset_plan_t *plan, hb_vector_t<char> &buf, hb_tag_t tag, bool *success)
29
72.2k
{
30
72.2k
#ifndef HB_NO_SUBSET_CFF
31
72.2k
  switch (tag)
32
72.2k
  {
33
0
  case HB_TAG('C','F','F',' '): *success = _hb_subset_table<const OT::cff1> (plan, buf); return true;
34
0
  case HB_TAG('C','F','F','2'): *success = _hb_subset_table<const OT::cff2> (plan, buf); return true;
35
0
  case HB_TAG('V','O','R','G'): *success = _hb_subset_table<const OT::VORG> (plan, buf); return true;
36
72.2k
  }
37
72.2k
#endif
38
72.2k
  return false;
39
72.2k
}
40
41
42
#ifdef HB_EXPERIMENTAL_API
43
#ifndef HB_NO_CFF
44
45
template<typename accel_t>
46
static hb_blob_t* get_charstrings_data(accel_t& accel, hb_codepoint_t glyph_index) {
47
  if (!accel.is_valid()) {
48
    return hb_blob_get_empty ();
49
  }
50
51
  hb_ubytes_t bytes = (*accel.charStrings)[glyph_index];
52
  if (!bytes) {
53
    return hb_blob_get_empty ();
54
  }
55
56
  hb_blob_t* cff_blob = accel.get_blob();
57
  uint32_t length;
58
  const char* cff_data = hb_blob_get_data(cff_blob, &length) ;
59
60
  long int offset = (const char*) bytes.arrayZ - cff_data;
61
  if (offset < 0 || offset > INT32_MAX) {
62
    return hb_blob_get_empty ();
63
  }
64
65
  return hb_blob_create_sub_blob(cff_blob, (uint32_t) offset, bytes.length);
66
}
67
68
template<typename accel_t>
69
static hb_blob_t* get_charstrings_index(accel_t& accel) {
70
  if (!accel.is_valid()) {
71
    return hb_blob_get_empty ();
72
  }
73
74
  const char* charstrings_start = (const char*) accel.charStrings;
75
  unsigned charstrings_length = accel.charStrings->get_size();
76
77
  hb_blob_t* cff_blob = accel.get_blob();
78
  uint32_t length;
79
  const char* cff_data = hb_blob_get_data(cff_blob, &length) ;
80
81
  long int offset = charstrings_start - cff_data;
82
  if (offset < 0 || offset > INT32_MAX) {
83
    return hb_blob_get_empty ();
84
  }
85
86
  return hb_blob_create_sub_blob(cff_blob, (uint32_t) offset, charstrings_length);
87
}
88
89
/**
90
 * hb_subset_cff_get_charstring_data:
91
 * @face: A face object
92
 * @glyph_index: Glyph index to get data for.
93
 *
94
 * Returns the raw outline data from the CFF/CFF2 table associated with the given glyph index.
95
 *
96
 * XSince: EXPERIMENTAL
97
 **/
98
HB_EXTERN hb_blob_t*
99
hb_subset_cff_get_charstring_data(hb_face_t* face, hb_codepoint_t glyph_index) {
100
  return get_charstrings_data(*face->table.cff1, glyph_index);
101
}
102
103
/**
104
 * hb_subset_cff_get_charstrings_index:
105
 * @face: A face object
106
 *
107
 * Returns the raw CFF CharStrings INDEX from the CFF table.
108
 *
109
 * XSince: EXPERIMENTAL
110
 **/
111
HB_EXTERN hb_blob_t*
112
hb_subset_cff_get_charstrings_index (hb_face_t* face) {
113
  return get_charstrings_index (*face->table.cff1);
114
}
115
116
/**
117
 * hb_subset_cff2_get_charstring_data:
118
 * @face: A face object
119
 * @glyph_index: Glyph index to get data for.
120
 *
121
 * Returns the raw outline data from the CFF/CFF2 table associated with the given glyph index.
122
 *
123
 * XSince: EXPERIMENTAL
124
 **/
125
HB_EXTERN hb_blob_t*
126
hb_subset_cff2_get_charstring_data(hb_face_t* face, hb_codepoint_t glyph_index) {
127
  return get_charstrings_data(*face->table.cff2, glyph_index);
128
}
129
130
/**
131
 * hb_subset_cff2_get_charstrings_index:
132
 * @face: A face object
133
 *
134
 * Returns the raw CFF2 CharStrings INDEX from the CFF2 table.
135
 *
136
 * XSince: EXPERIMENTAL
137
 **/
138
HB_EXTERN hb_blob_t*
139
hb_subset_cff2_get_charstrings_index (hb_face_t* face) {
140
  return get_charstrings_index (*face->table.cff2);
141
}
142
#endif
143
#endif