| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // A parser for the Type 2 Charstring Format. | 5 // A parser for the Type 2 Charstring Format. |
| 6 // http://www.adobe.com/devnet/font/pdfs/5177.Type2.pdf | 6 // http://www.adobe.com/devnet/font/pdfs/5177.Type2.pdf |
| 7 | 7 |
| 8 #include "cff_type2_charstring.h" | 8 #include "cff_type2_charstring.h" |
| 9 | 9 |
| 10 #include <climits> |
| 10 #include <cstdio> | 11 #include <cstdio> |
| 11 #include <cstring> | 12 #include <cstring> |
| 12 #include <limits> | |
| 13 #include <stack> | 13 #include <stack> |
| 14 #include <string> | 14 #include <string> |
| 15 #include <utility> | 15 #include <utility> |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 // The list of Operators. See Appendix. A in Adobe Technical Note #5177. | |
| 20 enum Type2CharStringOperator { | |
| 21 kHStem = 1, | |
| 22 kVStem = 3, | |
| 23 kVMoveTo = 4, | |
| 24 kRLineTo = 5, | |
| 25 kHLineTo = 6, | |
| 26 kVLineTo = 7, | |
| 27 kRRCurveTo = 8, | |
| 28 kCallSubr = 10, | |
| 29 kReturn = 11, | |
| 30 kEndChar = 14, | |
| 31 kHStemHm = 18, | |
| 32 kHintMask = 19, | |
| 33 kCntrMask = 20, | |
| 34 kRMoveTo = 21, | |
| 35 kHMoveTo = 22, | |
| 36 kVStemHm = 23, | |
| 37 kRCurveLine = 24, | |
| 38 kRLineCurve = 25, | |
| 39 kVVCurveTo = 26, | |
| 40 kHHCurveTo = 27, | |
| 41 kCallGSubr = 29, | |
| 42 kVHCurveTo = 30, | |
| 43 kHVCurveTo = 31, | |
| 44 kAnd = (12 << 8) + 3, | |
| 45 kOr = (12 << 8) + 4, | |
| 46 kNot = (12 << 8) + 5, | |
| 47 kAbs = (12 << 8) + 9, | |
| 48 kAdd = (12 << 8) + 10, | |
| 49 kSub = (12 << 8) + 11, | |
| 50 kDiv = (12 << 8) + 12, | |
| 51 kNeg = (12 << 8) + 14, | |
| 52 kEq = (12 << 8) + 15, | |
| 53 kDrop = (12 << 8) + 18, | |
| 54 kPut = (12 << 8) + 20, | |
| 55 kGet = (12 << 8) + 21, | |
| 56 kIfElse = (12 << 8) + 22, | |
| 57 kRandom = (12 << 8) + 23, | |
| 58 kMul = (12 << 8) + 24, | |
| 59 kSqrt = (12 << 8) + 26, | |
| 60 kDup = (12 << 8) + 27, | |
| 61 kExch = (12 << 8) + 28, | |
| 62 kIndex = (12 << 8) + 29, | |
| 63 kRoll = (12 << 8) + 30, | |
| 64 kHFlex = (12 << 8) + 34, | |
| 65 kFlex = (12 << 8) + 35, | |
| 66 kHFlex1 = (12 << 8) + 36, | |
| 67 kFlex1 = (12 << 8) + 37, | |
| 68 }; | |
| 69 | |
| 70 // Type 2 Charstring Implementation Limits. See Appendix. B in Adobe Technical | 19 // Type 2 Charstring Implementation Limits. See Appendix. B in Adobe Technical |
| 71 // Note #5177. | 20 // Note #5177. |
| 21 const int32_t kMaxSubrsCount = 65536; |
| 72 const size_t kMaxCharStringLength = 65535; | 22 const size_t kMaxCharStringLength = 65535; |
| 73 const size_t kMaxArgumentStack = 48; | 23 const size_t kMaxArgumentStack = 48; |
| 74 const size_t kMaxNumberOfStemHints = 96; | 24 const size_t kMaxNumberOfStemHints = 96; |
| 75 const size_t kMaxSubrNesting = 10; | 25 const size_t kMaxSubrNesting = 10; |
| 76 | 26 |
| 27 // |dummy_result| should be a huge positive integer so callsubr and callgsubr |
| 28 // will fail with the dummy value. |
| 29 const int32_t dummy_result = INT_MAX; |
| 30 |
| 77 bool ExecuteType2CharString(size_t call_depth, | 31 bool ExecuteType2CharString(size_t call_depth, |
| 78 const ots::CFFIndex& global_subrs_index, | 32 const ots::CFFIndex& global_subrs_index, |
| 79 const ots::CFFIndex& local_subrs_index, | 33 const ots::CFFIndex& local_subrs_index, |
| 80 ots::Buffer *cff_table, | 34 ots::Buffer *cff_table, |
| 81 ots::Buffer *char_string, | 35 ots::Buffer *char_string, |
| 82 std::stack<int32_t> *argument_stack, | 36 std::stack<int32_t> *argument_stack, |
| 83 bool *out_found_endchar, | 37 bool *out_found_endchar, |
| 84 bool *out_found_width, | 38 bool *out_found_width, |
| 85 size_t *in_out_num_stems); | 39 size_t *in_out_num_stems); |
| 86 | 40 |
| 87 // Converts |op| to a string and returns it. | 41 // Converts |op| to a string and returns it. |
| 88 const char *Type2CharStringOperatorToString(Type2CharStringOperator op) { | 42 const char *Type2CharStringOperatorToString(ots::Type2CharStringOperator op) { |
| 89 switch (op) { | 43 switch (op) { |
| 90 case kHStem: | 44 case ots::kHStem: |
| 91 return "HStem"; | 45 return "HStem"; |
| 92 case kVStem: | 46 case ots::kVStem: |
| 93 return "VStem"; | 47 return "VStem"; |
| 94 case kVMoveTo: | 48 case ots::kVMoveTo: |
| 95 return "VMoveTo"; | 49 return "VMoveTo"; |
| 96 case kRLineTo: | 50 case ots::kRLineTo: |
| 97 return "RLineTo"; | 51 return "RLineTo"; |
| 98 case kHLineTo: | 52 case ots::kHLineTo: |
| 99 return "HLineTo"; | 53 return "HLineTo"; |
| 100 case kVLineTo: | 54 case ots::kVLineTo: |
| 101 return "VLineTo"; | 55 return "VLineTo"; |
| 102 case kRRCurveTo: | 56 case ots::kRRCurveTo: |
| 103 return "RRCurveTo"; | 57 return "RRCurveTo"; |
| 104 case kCallSubr: | 58 case ots::kCallSubr: |
| 105 return "CallSubr"; | 59 return "CallSubr"; |
| 106 case kReturn: | 60 case ots::kReturn: |
| 107 return "Return"; | 61 return "Return"; |
| 108 case kEndChar: | 62 case ots::kEndChar: |
| 109 return "EndChar"; | 63 return "EndChar"; |
| 110 case kHStemHm: | 64 case ots::kHStemHm: |
| 111 return "HStemHm"; | 65 return "HStemHm"; |
| 112 case kHintMask: | 66 case ots::kHintMask: |
| 113 return "HintMask"; | 67 return "HintMask"; |
| 114 case kCntrMask: | 68 case ots::kCntrMask: |
| 115 return "CntrMask"; | 69 return "CntrMask"; |
| 116 case kRMoveTo: | 70 case ots::kRMoveTo: |
| 117 return "RMoveTo"; | 71 return "RMoveTo"; |
| 118 case kHMoveTo: | 72 case ots::kHMoveTo: |
| 119 return "HMoveTo"; | 73 return "HMoveTo"; |
| 120 case kVStemHm: | 74 case ots::kVStemHm: |
| 121 return "VStemHm"; | 75 return "VStemHm"; |
| 122 case kRCurveLine: | 76 case ots::kRCurveLine: |
| 123 return "RCurveLine"; | 77 return "RCurveLine"; |
| 124 case kRLineCurve: | 78 case ots::kRLineCurve: |
| 125 return "RLineCurve"; | 79 return "RLineCurve"; |
| 126 case kVVCurveTo: | 80 case ots::kVVCurveTo: |
| 127 return "VVCurveTo"; | 81 return "VVCurveTo"; |
| 128 case kHHCurveTo: | 82 case ots::kHHCurveTo: |
| 129 return "HHCurveTo"; | 83 return "HHCurveTo"; |
| 130 case kCallGSubr: | 84 case ots::kCallGSubr: |
| 131 return "CallGSubr"; | 85 return "CallGSubr"; |
| 132 case kVHCurveTo: | 86 case ots::kVHCurveTo: |
| 133 return "VHCurveTo"; | 87 return "VHCurveTo"; |
| 134 case kHVCurveTo: | 88 case ots::kHVCurveTo: |
| 135 return "HVCurveTo"; | 89 return "HVCurveTo"; |
| 136 case kAnd: | 90 case ots::kAnd: |
| 137 return "And"; | 91 return "And"; |
| 138 case kOr: | 92 case ots::kOr: |
| 139 return "Or"; | 93 return "Or"; |
| 140 case kNot: | 94 case ots::kNot: |
| 141 return "Not"; | 95 return "Not"; |
| 142 case kAbs: | 96 case ots::kAbs: |
| 143 return "Abs"; | 97 return "Abs"; |
| 144 case kAdd: | 98 case ots::kAdd: |
| 145 return "Add"; | 99 return "Add"; |
| 146 case kSub: | 100 case ots::kSub: |
| 147 return "Sub"; | 101 return "Sub"; |
| 148 case kDiv: | 102 case ots::kDiv: |
| 149 return "Div"; | 103 return "Div"; |
| 150 case kNeg: | 104 case ots::kNeg: |
| 151 return "Neg"; | 105 return "Neg"; |
| 152 case kEq: | 106 case ots::kEq: |
| 153 return "Eq"; | 107 return "Eq"; |
| 154 case kDrop: | 108 case ots::kDrop: |
| 155 return "Drop"; | 109 return "Drop"; |
| 156 case kPut: | 110 case ots::kPut: |
| 157 return "Put"; | 111 return "Put"; |
| 158 case kGet: | 112 case ots::kGet: |
| 159 return "Get"; | 113 return "Get"; |
| 160 case kIfElse: | 114 case ots::kIfElse: |
| 161 return "IfElse"; | 115 return "IfElse"; |
| 162 case kRandom: | 116 case ots::kRandom: |
| 163 return "Random"; | 117 return "Random"; |
| 164 case kMul: | 118 case ots::kMul: |
| 165 return "Mul"; | 119 return "Mul"; |
| 166 case kSqrt: | 120 case ots::kSqrt: |
| 167 return "Sqrt"; | 121 return "Sqrt"; |
| 168 case kDup: | 122 case ots::kDup: |
| 169 return "Dup"; | 123 return "Dup"; |
| 170 case kExch: | 124 case ots::kExch: |
| 171 return "Exch"; | 125 return "Exch"; |
| 172 case kIndex: | 126 case ots::kIndex: |
| 173 return "Index"; | 127 return "Index"; |
| 174 case kRoll: | 128 case ots::kRoll: |
| 175 return "Roll"; | 129 return "Roll"; |
| 176 case kHFlex: | 130 case ots::kHFlex: |
| 177 return "HFlex"; | 131 return "HFlex"; |
| 178 case kFlex: | 132 case ots::kFlex: |
| 179 return "Flex"; | 133 return "Flex"; |
| 180 case kHFlex1: | 134 case ots::kHFlex1: |
| 181 return "HFlex1"; | 135 return "HFlex1"; |
| 182 case kFlex1: | 136 case ots::kFlex1: |
| 183 return "Flex1"; | 137 return "Flex1"; |
| 184 } | 138 } |
| 185 | 139 |
| 186 return "UNKNOWN"; | 140 return "UNKNOWN"; |
| 187 } | 141 } |
| 188 | 142 |
| 189 // Read one or more bytes from the |char_string| buffer and stores the number | 143 // Read one or more bytes from the |char_string| buffer and stores the number |
| 190 // read on |out_number|. If the number read is an operator (ex 'vstem'), sets | 144 // read on |out_number|. If the number read is an operator (ex 'vstem'), sets |
| 191 // true on |out_is_operator|. Returns true if the function read a number. | 145 // true on |out_is_operator|. Returns true if the function read a number. |
| 192 bool ReadNextNumberFromType2CharString(ots::Buffer *char_string, | 146 bool ReadNextNumberFromType2CharString(ots::Buffer *char_string, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 *out_number = ((static_cast<int32_t>(v) - 247) * 256) + | 193 *out_number = ((static_cast<int32_t>(v) - 247) * 256) + |
| 240 static_cast<int32_t>(w) + 108; | 194 static_cast<int32_t>(w) + 108; |
| 241 } else if (v <= 254) { | 195 } else if (v <= 254) { |
| 242 uint8_t w = 0; | 196 uint8_t w = 0; |
| 243 if (!char_string->ReadU8(&w)) { | 197 if (!char_string->ReadU8(&w)) { |
| 244 return OTS_FAILURE(); | 198 return OTS_FAILURE(); |
| 245 } | 199 } |
| 246 *out_number = -((static_cast<int32_t>(v) - 251) * 256) - | 200 *out_number = -((static_cast<int32_t>(v) - 251) * 256) - |
| 247 static_cast<int32_t>(w) - 108; | 201 static_cast<int32_t>(w) - 108; |
| 248 } else if (v == 255) { | 202 } else if (v == 255) { |
| 249 uint32_t result = 0; | 203 // TODO(yusukes): We should not skip the 4 bytes. Note that when v is 255, |
| 250 for (size_t i = 0; i < 4; ++i) { | 204 // we should treat the following 4-bytes as a 16.16 fixed-point number |
| 251 if (!char_string->ReadU8(&v)) { | 205 // rather than 32bit signed int. |
| 252 return OTS_FAILURE(); | 206 if (!char_string->Skip(4)) { |
| 253 } | 207 return OTS_FAILURE(); |
| 254 result = (result << 8) + v; | |
| 255 } | 208 } |
| 256 // TODO(yusukes): |result| should be treated as 16.16 fixed-point number | 209 *out_number = dummy_result; |
| 257 // rather than 32bit signed int. | |
| 258 *out_number = static_cast<int32_t>(result); | |
| 259 } else { | 210 } else { |
| 260 return OTS_FAILURE(); | 211 return OTS_FAILURE(); |
| 261 } | 212 } |
| 262 | 213 |
| 263 return true; | 214 return true; |
| 264 } | 215 } |
| 265 | 216 |
| 266 // Executes |op| and updates |argument_stack|. Returns true if the execution | 217 // Executes |op| and updates |argument_stack|. Returns true if the execution |
| 267 // succeeds. If the |op| is kCallSubr or kCallGSubr, the function recursively | 218 // succeeds. If the |op| is kCallSubr or kCallGSubr, the function recursively |
| 268 // calls ExecuteType2CharString() function. The arguments other than |op| and | 219 // calls ExecuteType2CharString() function. The arguments other than |op| and |
| 269 // |argument_stack| are passed for that reason. | 220 // |argument_stack| are passed for that reason. |
| 270 bool ExecuteType2CharStringOperator(int32_t op, | 221 bool ExecuteType2CharStringOperator(int32_t op, |
| 271 size_t call_depth, | 222 size_t call_depth, |
| 272 const ots::CFFIndex& global_subrs_index, | 223 const ots::CFFIndex& global_subrs_index, |
| 273 const ots::CFFIndex& local_subrs_index, | 224 const ots::CFFIndex& local_subrs_index, |
| 274 ots::Buffer *cff_table, | 225 ots::Buffer *cff_table, |
| 275 ots::Buffer *char_string, | 226 ots::Buffer *char_string, |
| 276 std::stack<int32_t> *argument_stack, | 227 std::stack<int32_t> *argument_stack, |
| 277 bool *out_found_endchar, | 228 bool *out_found_endchar, |
| 278 bool *in_out_found_width, | 229 bool *in_out_found_width, |
| 279 size_t *in_out_num_stems) { | 230 size_t *in_out_num_stems) { |
| 280 // |dummy_result| should be a huge positive integer so callsubr and callgsubr | |
| 281 // will fail with the dummy value. | |
| 282 const int32_t dummy_result = std::numeric_limits<int>::max(); | |
| 283 const size_t stack_size = argument_stack->size(); | 231 const size_t stack_size = argument_stack->size(); |
| 284 | 232 |
| 285 switch (op) { | 233 switch (op) { |
| 286 case kCallSubr: | 234 case ots::kCallSubr: |
| 287 case kCallGSubr: { | 235 case ots::kCallGSubr: { |
| 288 const ots::CFFIndex& subrs_index = | 236 const ots::CFFIndex& subrs_index = |
| 289 (op == kCallSubr ? local_subrs_index : global_subrs_index); | 237 (op == ots::kCallSubr ? local_subrs_index : global_subrs_index); |
| 290 | 238 |
| 291 if (stack_size < 1) { | 239 if (stack_size < 1) { |
| 292 return OTS_FAILURE(); | 240 return OTS_FAILURE(); |
| 293 } | 241 } |
| 294 int32_t subr_number = argument_stack->top(); | 242 int32_t subr_number = argument_stack->top(); |
| 295 argument_stack->pop(); | 243 argument_stack->pop(); |
| 296 if (subr_number == dummy_result) { | 244 if (subr_number == dummy_result) { |
| 297 // For safety, we allow subr calls only with immediate subr numbers for | 245 // For safety, we allow subr calls only with immediate subr numbers for |
| 298 // now. For example, we allow "123 callgsubr", but does not allow "100 12 | 246 // now. For example, we allow "123 callgsubr", but does not allow "100 12 |
| 299 // add callgsubr". Please note that arithmetic and conditional operators | 247 // add callgsubr". Please note that arithmetic and conditional operators |
| 300 // always push the |dummy_result| in this implementation. | 248 // always push the |dummy_result| in this implementation. |
| 301 return OTS_FAILURE(); | 249 return OTS_FAILURE(); |
| 302 } | 250 } |
| 303 | 251 |
| 304 // See Adobe Technical Note #5176 (CFF), "16. Local/GlobalSubrs INDEXes." | 252 // See Adobe Technical Note #5176 (CFF), "16. Local/GlobalSubrs INDEXes." |
| 305 int32_t bias = 32768; | 253 int32_t bias = 32768; |
| 306 if (subrs_index.count < 1240) { | 254 if (subrs_index.count < 1240) { |
| 307 bias = 107; | 255 bias = 107; |
| 308 } else if (subrs_index.count < 33900) { | 256 } else if (subrs_index.count < 33900) { |
| 309 bias = 1131; | 257 bias = 1131; |
| 310 } | 258 } |
| 311 subr_number += bias; | 259 subr_number += bias; |
| 312 | 260 |
| 313 // Sanity checks of |subr_number|. | 261 // Sanity checks of |subr_number|. |
| 314 if (subr_number < 0) { | 262 if (subr_number < 0) { |
| 315 return OTS_FAILURE(); | 263 return OTS_FAILURE(); |
| 316 } | 264 } |
| 317 if (subrs_index.offsets.size() <= static_cast<size_t>(subr_number)) { | 265 if (subr_number >= kMaxSubrsCount) { |
| 266 return OTS_FAILURE(); |
| 267 } |
| 268 if (subrs_index.offsets.size() <= static_cast<size_t>(subr_number + 1)) { |
| 318 return OTS_FAILURE(); // The number is out-of-bounds. | 269 return OTS_FAILURE(); // The number is out-of-bounds. |
| 319 } | 270 } |
| 320 | 271 |
| 321 // Prepare ots::Buffer where we're going to jump. | 272 // Prepare ots::Buffer where we're going to jump. |
| 322 const size_t length = | 273 const size_t length = |
| 323 subrs_index.offsets[subr_number + 1] - subrs_index.offsets[subr_number]; | 274 subrs_index.offsets[subr_number + 1] - subrs_index.offsets[subr_number]; |
| 324 if (length > kMaxCharStringLength) { | 275 if (length > kMaxCharStringLength) { |
| 325 return OTS_FAILURE(); | 276 return OTS_FAILURE(); |
| 326 } | 277 } |
| 327 const size_t offset = subrs_index.offsets[subr_number]; | 278 const size_t offset = subrs_index.offsets[subr_number]; |
| 328 cff_table->set_offset(offset); | 279 cff_table->set_offset(offset); |
| 329 if (!cff_table->Skip(length)) { | 280 if (!cff_table->Skip(length)) { |
| 330 return OTS_FAILURE(); | 281 return OTS_FAILURE(); |
| 331 } | 282 } |
| 332 ots::Buffer char_string_to_jump(cff_table->buffer() + offset, length); | 283 ots::Buffer char_string_to_jump(cff_table->buffer() + offset, length); |
| 333 | 284 |
| 334 return ExecuteType2CharString(call_depth + 1, | 285 return ExecuteType2CharString(call_depth + 1, |
| 335 global_subrs_index, | 286 global_subrs_index, |
| 336 local_subrs_index, | 287 local_subrs_index, |
| 337 cff_table, | 288 cff_table, |
| 338 &char_string_to_jump, | 289 &char_string_to_jump, |
| 339 argument_stack, | 290 argument_stack, |
| 340 out_found_endchar, | 291 out_found_endchar, |
| 341 in_out_found_width, | 292 in_out_found_width, |
| 342 in_out_num_stems); | 293 in_out_num_stems); |
| 343 } | 294 } |
| 344 | 295 |
| 345 case kReturn: | 296 case ots::kReturn: |
| 346 return true; | 297 return true; |
| 347 | 298 |
| 348 case kEndChar: | 299 case ots::kEndChar: |
| 349 *out_found_endchar = true; | 300 *out_found_endchar = true; |
| 350 *in_out_found_width = true; // just in case. | 301 *in_out_found_width = true; // just in case. |
| 351 return true; | 302 return true; |
| 352 | 303 |
| 353 case kHStem: | 304 case ots::kHStem: |
| 354 case kVStem: | 305 case ots::kVStem: |
| 355 case kHStemHm: | 306 case ots::kHStemHm: |
| 356 case kVStemHm: { | 307 case ots::kVStemHm: { |
| 357 bool successful = false; | 308 bool successful = false; |
| 358 if (stack_size < 2) { | 309 if (stack_size < 2) { |
| 359 return OTS_FAILURE(); | 310 return OTS_FAILURE(); |
| 360 } | 311 } |
| 361 if ((stack_size % 2) == 0) { | 312 if ((stack_size % 2) == 0) { |
| 362 successful = true; | 313 successful = true; |
| 363 } else if ((!(*in_out_found_width)) && (((stack_size - 1) % 2) == 0)) { | 314 } else if ((!(*in_out_found_width)) && (((stack_size - 1) % 2) == 0)) { |
| 364 // The -1 is for "width" argument. For details, see Adobe Technical Note | 315 // The -1 is for "width" argument. For details, see Adobe Technical Note |
| 365 // #5177, page 16, note 4. | 316 // #5177, page 16, note 4. |
| 366 successful = true; | 317 successful = true; |
| 367 } | 318 } |
| 368 (*in_out_num_stems) += (stack_size / 2); | 319 (*in_out_num_stems) += (stack_size / 2); |
| 369 if ((*in_out_num_stems) > kMaxNumberOfStemHints) { | 320 if ((*in_out_num_stems) > kMaxNumberOfStemHints) { |
| 370 return OTS_FAILURE(); | 321 return OTS_FAILURE(); |
| 371 } | 322 } |
| 372 while (!argument_stack->empty()) | 323 while (!argument_stack->empty()) |
| 373 argument_stack->pop(); | 324 argument_stack->pop(); |
| 374 *in_out_found_width = true; // always set true since "w" might be 0 byte. | 325 *in_out_found_width = true; // always set true since "w" might be 0 byte. |
| 375 return successful ? true : OTS_FAILURE(); | 326 return successful ? true : OTS_FAILURE(); |
| 376 } | 327 } |
| 377 | 328 |
| 378 case kRMoveTo: { | 329 case ots::kRMoveTo: { |
| 379 bool successful = false; | 330 bool successful = false; |
| 380 if (stack_size == 2) { | 331 if (stack_size == 2) { |
| 381 successful = true; | 332 successful = true; |
| 382 } else if ((!(*in_out_found_width)) && (stack_size - 1 == 2)) { | 333 } else if ((!(*in_out_found_width)) && (stack_size - 1 == 2)) { |
| 383 successful = true; | 334 successful = true; |
| 384 } | 335 } |
| 385 while (!argument_stack->empty()) | 336 while (!argument_stack->empty()) |
| 386 argument_stack->pop(); | 337 argument_stack->pop(); |
| 387 *in_out_found_width = true; | 338 *in_out_found_width = true; |
| 388 return successful ? true : OTS_FAILURE(); | 339 return successful ? true : OTS_FAILURE(); |
| 389 } | 340 } |
| 390 | 341 |
| 391 case kVMoveTo: | 342 case ots::kVMoveTo: |
| 392 case kHMoveTo: { | 343 case ots::kHMoveTo: { |
| 393 bool successful = false; | 344 bool successful = false; |
| 394 if (stack_size == 1) { | 345 if (stack_size == 1) { |
| 395 successful = true; | 346 successful = true; |
| 396 } else if ((!(*in_out_found_width)) && (stack_size - 1 == 1)) { | 347 } else if ((!(*in_out_found_width)) && (stack_size - 1 == 1)) { |
| 397 successful = true; | 348 successful = true; |
| 398 } | 349 } |
| 399 while (!argument_stack->empty()) | 350 while (!argument_stack->empty()) |
| 400 argument_stack->pop(); | 351 argument_stack->pop(); |
| 401 *in_out_found_width = true; | 352 *in_out_found_width = true; |
| 402 return successful ? true : OTS_FAILURE(); | 353 return successful ? true : OTS_FAILURE(); |
| 403 } | 354 } |
| 404 | 355 |
| 405 case kHintMask: | 356 case ots::kHintMask: |
| 406 case kCntrMask: { | 357 case ots::kCntrMask: { |
| 407 bool successful = false; | 358 bool successful = false; |
| 408 if (stack_size == 0) { | 359 if (stack_size == 0) { |
| 409 successful = true; | 360 successful = true; |
| 410 } else if ((!(*in_out_found_width)) && (stack_size == 1)) { | 361 } else if ((!(*in_out_found_width)) && (stack_size == 1)) { |
| 411 // A number for "width" is found. | 362 // A number for "width" is found. |
| 412 successful = true; | 363 successful = true; |
| 413 } else if ((!(*in_out_found_width)) || // in this case, any sizes are ok. | 364 } else if ((!(*in_out_found_width)) || // in this case, any sizes are ok. |
| 414 ((stack_size % 2) == 0)) { | 365 ((stack_size % 2) == 0)) { |
| 415 // The numbers are vstem definition. | 366 // The numbers are vstem definition. |
| 416 // See Adobe Technical Note #5177, page 24, hintmask. | 367 // See Adobe Technical Note #5177, page 24, hintmask. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 430 const size_t mask_bytes = (*in_out_num_stems + 7) / 8; | 381 const size_t mask_bytes = (*in_out_num_stems + 7) / 8; |
| 431 if (!char_string->Skip(mask_bytes)) { | 382 if (!char_string->Skip(mask_bytes)) { |
| 432 return OTS_FAILURE(); | 383 return OTS_FAILURE(); |
| 433 } | 384 } |
| 434 while (!argument_stack->empty()) | 385 while (!argument_stack->empty()) |
| 435 argument_stack->pop(); | 386 argument_stack->pop(); |
| 436 *in_out_found_width = true; | 387 *in_out_found_width = true; |
| 437 return true; | 388 return true; |
| 438 } | 389 } |
| 439 | 390 |
| 440 case kRLineTo: | 391 case ots::kRLineTo: |
| 441 if (!(*in_out_found_width)) { | 392 if (!(*in_out_found_width)) { |
| 442 // The first stack-clearing operator should be one of hstem, hstemhm, | 393 // The first stack-clearing operator should be one of hstem, hstemhm, |
| 443 // vstem, vstemhm, cntrmask, hintmask, hmoveto, vmoveto, rmoveto, or | 394 // vstem, vstemhm, cntrmask, hintmask, hmoveto, vmoveto, rmoveto, or |
| 444 // endchar. For details, see Adobe Technical Note #5177, page 16, note 4. | 395 // endchar. For details, see Adobe Technical Note #5177, page 16, note 4. |
| 445 return OTS_FAILURE(); | 396 return OTS_FAILURE(); |
| 446 } | 397 } |
| 447 if (stack_size < 2) { | 398 if (stack_size < 2) { |
| 448 return OTS_FAILURE(); | 399 return OTS_FAILURE(); |
| 449 } | 400 } |
| 450 if ((stack_size % 2) != 0) { | 401 if ((stack_size % 2) != 0) { |
| 451 return OTS_FAILURE(); | 402 return OTS_FAILURE(); |
| 452 } | 403 } |
| 453 while (!argument_stack->empty()) | 404 while (!argument_stack->empty()) |
| 454 argument_stack->pop(); | 405 argument_stack->pop(); |
| 455 return true; | 406 return true; |
| 456 | 407 |
| 457 case kHLineTo: | 408 case ots::kHLineTo: |
| 458 case kVLineTo: | 409 case ots::kVLineTo: |
| 459 if (!(*in_out_found_width)) { | 410 if (!(*in_out_found_width)) { |
| 460 return OTS_FAILURE(); | 411 return OTS_FAILURE(); |
| 461 } | 412 } |
| 462 if (stack_size < 1) { | 413 if (stack_size < 1) { |
| 463 return OTS_FAILURE(); | 414 return OTS_FAILURE(); |
| 464 } | 415 } |
| 465 while (!argument_stack->empty()) | 416 while (!argument_stack->empty()) |
| 466 argument_stack->pop(); | 417 argument_stack->pop(); |
| 467 return true; | 418 return true; |
| 468 | 419 |
| 469 case kRRCurveTo: | 420 case ots::kRRCurveTo: |
| 470 if (!(*in_out_found_width)) { | 421 if (!(*in_out_found_width)) { |
| 471 return OTS_FAILURE(); | 422 return OTS_FAILURE(); |
| 472 } | 423 } |
| 473 if (stack_size < 6) { | 424 if (stack_size < 6) { |
| 474 return OTS_FAILURE(); | 425 return OTS_FAILURE(); |
| 475 } | 426 } |
| 476 if ((stack_size % 6) != 0) { | 427 if ((stack_size % 6) != 0) { |
| 477 return OTS_FAILURE(); | 428 return OTS_FAILURE(); |
| 478 } | 429 } |
| 479 while (!argument_stack->empty()) | 430 while (!argument_stack->empty()) |
| 480 argument_stack->pop(); | 431 argument_stack->pop(); |
| 481 return true; | 432 return true; |
| 482 | 433 |
| 483 case kRCurveLine: | 434 case ots::kRCurveLine: |
| 484 if (!(*in_out_found_width)) { | 435 if (!(*in_out_found_width)) { |
| 485 return OTS_FAILURE(); | 436 return OTS_FAILURE(); |
| 486 } | 437 } |
| 487 if (stack_size < 8) { | 438 if (stack_size < 8) { |
| 488 return OTS_FAILURE(); | 439 return OTS_FAILURE(); |
| 489 } | 440 } |
| 490 if (((stack_size - 2) % 6) != 0) { | 441 if (((stack_size - 2) % 6) != 0) { |
| 491 return OTS_FAILURE(); | 442 return OTS_FAILURE(); |
| 492 } | 443 } |
| 493 while (!argument_stack->empty()) | 444 while (!argument_stack->empty()) |
| 494 argument_stack->pop(); | 445 argument_stack->pop(); |
| 495 return true; | 446 return true; |
| 496 | 447 |
| 497 case kRLineCurve: | 448 case ots::kRLineCurve: |
| 498 if (!(*in_out_found_width)) { | 449 if (!(*in_out_found_width)) { |
| 499 return OTS_FAILURE(); | 450 return OTS_FAILURE(); |
| 500 } | 451 } |
| 501 if (stack_size < 8) { | 452 if (stack_size < 8) { |
| 502 return OTS_FAILURE(); | 453 return OTS_FAILURE(); |
| 503 } | 454 } |
| 504 if (((stack_size - 6) % 2) != 0) { | 455 if (((stack_size - 6) % 2) != 0) { |
| 505 return OTS_FAILURE(); | 456 return OTS_FAILURE(); |
| 506 } | 457 } |
| 507 while (!argument_stack->empty()) | 458 while (!argument_stack->empty()) |
| 508 argument_stack->pop(); | 459 argument_stack->pop(); |
| 509 return true; | 460 return true; |
| 510 | 461 |
| 511 case kVVCurveTo: | 462 case ots::kVVCurveTo: |
| 512 if (!(*in_out_found_width)) { | 463 if (!(*in_out_found_width)) { |
| 513 return OTS_FAILURE(); | 464 return OTS_FAILURE(); |
| 514 } | 465 } |
| 515 if (stack_size < 4) { | 466 if (stack_size < 4) { |
| 516 return OTS_FAILURE(); | 467 return OTS_FAILURE(); |
| 517 } | 468 } |
| 518 if (((stack_size % 4) != 0) && | 469 if (((stack_size % 4) != 0) && |
| 519 (((stack_size - 1) % 4) != 0)) { | 470 (((stack_size - 1) % 4) != 0)) { |
| 520 return OTS_FAILURE(); | 471 return OTS_FAILURE(); |
| 521 } | 472 } |
| 522 while (!argument_stack->empty()) | 473 while (!argument_stack->empty()) |
| 523 argument_stack->pop(); | 474 argument_stack->pop(); |
| 524 return true; | 475 return true; |
| 525 | 476 |
| 526 case kHHCurveTo: { | 477 case ots::kHHCurveTo: { |
| 527 bool successful = false; | 478 bool successful = false; |
| 528 if (!(*in_out_found_width)) { | 479 if (!(*in_out_found_width)) { |
| 529 return OTS_FAILURE(); | 480 return OTS_FAILURE(); |
| 530 } | 481 } |
| 531 if (stack_size < 4) { | 482 if (stack_size < 4) { |
| 532 return OTS_FAILURE(); | 483 return OTS_FAILURE(); |
| 533 } | 484 } |
| 534 if ((stack_size % 4) == 0) { | 485 if ((stack_size % 4) == 0) { |
| 535 // {dxa dxb dyb dxc}+ | 486 // {dxa dxb dyb dxc}+ |
| 536 successful = true; | 487 successful = true; |
| 537 } else if (((stack_size - 1) % 4) == 0) { | 488 } else if (((stack_size - 1) % 4) == 0) { |
| 538 // dy1? {dxa dxb dyb dxc}+ | 489 // dy1? {dxa dxb dyb dxc}+ |
| 539 successful = true; | 490 successful = true; |
| 540 } | 491 } |
| 541 while (!argument_stack->empty()) | 492 while (!argument_stack->empty()) |
| 542 argument_stack->pop(); | 493 argument_stack->pop(); |
| 543 return successful ? true : OTS_FAILURE(); | 494 return successful ? true : OTS_FAILURE(); |
| 544 } | 495 } |
| 545 | 496 |
| 546 case kVHCurveTo: | 497 case ots::kVHCurveTo: |
| 547 case kHVCurveTo: { | 498 case ots::kHVCurveTo: { |
| 548 bool successful = false; | 499 bool successful = false; |
| 549 if (!(*in_out_found_width)) { | 500 if (!(*in_out_found_width)) { |
| 550 return OTS_FAILURE(); | 501 return OTS_FAILURE(); |
| 551 } | 502 } |
| 552 if (stack_size < 4) { | 503 if (stack_size < 4) { |
| 553 return OTS_FAILURE(); | 504 return OTS_FAILURE(); |
| 554 } | 505 } |
| 555 if (((stack_size - 4) % 8) == 0) { | 506 if (((stack_size - 4) % 8) == 0) { |
| 556 // dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* | 507 // dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* |
| 557 successful = true; | 508 successful = true; |
| 558 } else if ((stack_size >= 5) && | 509 } else if ((stack_size >= 5) && |
| 559 ((stack_size - 5) % 8) == 0) { | 510 ((stack_size - 5) % 8) == 0) { |
| 560 // dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* dxf | 511 // dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* dxf |
| 561 successful = true; | 512 successful = true; |
| 562 } else if ((stack_size >= 8) && | 513 } else if ((stack_size >= 8) && |
| 563 ((stack_size - 8) % 8) == 0) { | 514 ((stack_size - 8) % 8) == 0) { |
| 564 // {dxa dxb dyb dyc dyd dxe dye dxf}+ | 515 // {dxa dxb dyb dyc dyd dxe dye dxf}+ |
| 565 successful = true; | 516 successful = true; |
| 566 } else if ((stack_size >= 9) && | 517 } else if ((stack_size >= 9) && |
| 567 ((stack_size - 9) % 8) == 0) { | 518 ((stack_size - 9) % 8) == 0) { |
| 568 // {dxa dxb dyb dyc dyd dxe dye dxf}+ dyf? | 519 // {dxa dxb dyb dyc dyd dxe dye dxf}+ dyf? |
| 569 successful = true; | 520 successful = true; |
| 570 } | 521 } |
| 571 while (!argument_stack->empty()) | 522 while (!argument_stack->empty()) |
| 572 argument_stack->pop(); | 523 argument_stack->pop(); |
| 573 return successful ? true : OTS_FAILURE(); | 524 return successful ? true : OTS_FAILURE(); |
| 574 } | 525 } |
| 575 | 526 |
| 576 case kAnd: | 527 case ots::kAnd: |
| 577 case kOr: | 528 case ots::kOr: |
| 578 case kEq: | 529 case ots::kEq: |
| 579 case kAdd: | 530 case ots::kAdd: |
| 580 case kSub: | 531 case ots::kSub: |
| 581 if (stack_size < 2) { | 532 if (stack_size < 2) { |
| 582 return OTS_FAILURE(); | 533 return OTS_FAILURE(); |
| 583 } | 534 } |
| 584 argument_stack->pop(); | 535 argument_stack->pop(); |
| 585 argument_stack->pop(); | 536 argument_stack->pop(); |
| 586 argument_stack->push(dummy_result); | 537 argument_stack->push(dummy_result); |
| 587 // TODO(yusukes): Implement this. We should push a real value for all | 538 // TODO(yusukes): Implement this. We should push a real value for all |
| 588 // arithmetic and conditional operations. | 539 // arithmetic and conditional operations. |
| 589 return true; | 540 return true; |
| 590 | 541 |
| 591 case kNot: | 542 case ots::kNot: |
| 592 case kAbs: | 543 case ots::kAbs: |
| 593 case kNeg: | 544 case ots::kNeg: |
| 594 if (stack_size < 1) { | 545 if (stack_size < 1) { |
| 595 return OTS_FAILURE(); | 546 return OTS_FAILURE(); |
| 596 } | 547 } |
| 597 argument_stack->pop(); | 548 argument_stack->pop(); |
| 598 argument_stack->push(dummy_result); | 549 argument_stack->push(dummy_result); |
| 599 // TODO(yusukes): Implement this. We should push a real value for all | 550 // TODO(yusukes): Implement this. We should push a real value for all |
| 600 // arithmetic and conditional operations. | 551 // arithmetic and conditional operations. |
| 601 return true; | 552 return true; |
| 602 | 553 |
| 603 case kDiv: | 554 case ots::kDiv: |
| 604 // TODO(yusukes): Should detect div-by-zero errors. | 555 // TODO(yusukes): Should detect div-by-zero errors. |
| 605 if (stack_size < 1) { | 556 if (stack_size < 2) { |
| 606 return OTS_FAILURE(); | 557 return OTS_FAILURE(); |
| 607 } | 558 } |
| 608 argument_stack->pop(); | 559 argument_stack->pop(); |
| 560 argument_stack->pop(); |
| 609 argument_stack->push(dummy_result); | 561 argument_stack->push(dummy_result); |
| 610 // TODO(yusukes): Implement this. We should push a real value for all | 562 // TODO(yusukes): Implement this. We should push a real value for all |
| 611 // arithmetic and conditional operations. | 563 // arithmetic and conditional operations. |
| 612 return true; | 564 return true; |
| 613 | 565 |
| 614 case kDrop: | 566 case ots::kDrop: |
| 615 if (stack_size < 1) { | 567 if (stack_size < 1) { |
| 616 return OTS_FAILURE(); | 568 return OTS_FAILURE(); |
| 617 } | 569 } |
| 618 argument_stack->pop(); | 570 argument_stack->pop(); |
| 619 return true; | 571 return true; |
| 620 | 572 |
| 621 case kPut: | 573 case ots::kPut: |
| 622 case kGet: | 574 case ots::kGet: |
| 623 case kIndex: | 575 case ots::kIndex: |
| 624 // For now, just call OTS_FAILURE since there is no way to check whether the | 576 // For now, just call OTS_FAILURE since there is no way to check whether the |
| 625 // index argument, |i|, is out-of-bounds or not. Fortunately, no OpenType | 577 // index argument, |i|, is out-of-bounds or not. Fortunately, no OpenType |
| 626 // fonts I have (except malicious ones!) use the operators. | 578 // fonts I have (except malicious ones!) use the operators. |
| 627 // TODO(yusukes): Implement them in a secure way. | 579 // TODO(yusukes): Implement them in a secure way. |
| 628 return OTS_FAILURE(); | 580 return OTS_FAILURE(); |
| 629 | 581 |
| 630 case kRoll: | 582 case ots::kRoll: |
| 631 // Likewise, just call OTS_FAILURE for kRoll since there is no way to check | 583 // Likewise, just call OTS_FAILURE for kRoll since there is no way to check |
| 632 // whether |N| is smaller than the current stack depth or not. | 584 // whether |N| is smaller than the current stack depth or not. |
| 633 // TODO(yusukes): Implement them in a secure way. | 585 // TODO(yusukes): Implement them in a secure way. |
| 634 return OTS_FAILURE(); | 586 return OTS_FAILURE(); |
| 635 | 587 |
| 636 case kRandom: | 588 case ots::kRandom: |
| 637 // For now, we don't handle the 'random' operator since the operator makes | 589 // For now, we don't handle the 'random' operator since the operator makes |
| 638 // it hard to analyze hinting code statically. | 590 // it hard to analyze hinting code statically. |
| 639 return OTS_FAILURE(); | 591 return OTS_FAILURE(); |
| 640 | 592 |
| 641 case kIfElse: | 593 case ots::kIfElse: |
| 642 if (stack_size < 4) { | 594 if (stack_size < 4) { |
| 643 return OTS_FAILURE(); | 595 return OTS_FAILURE(); |
| 644 } | 596 } |
| 645 argument_stack->pop(); | 597 argument_stack->pop(); |
| 646 argument_stack->pop(); | 598 argument_stack->pop(); |
| 647 argument_stack->pop(); | 599 argument_stack->pop(); |
| 648 argument_stack->pop(); | 600 argument_stack->pop(); |
| 649 argument_stack->push(dummy_result); | 601 argument_stack->push(dummy_result); |
| 650 // TODO(yusukes): Implement this. We should push a real value for all | 602 // TODO(yusukes): Implement this. We should push a real value for all |
| 651 // arithmetic and conditional operations. | 603 // arithmetic and conditional operations. |
| 652 return true; | 604 return true; |
| 653 | 605 |
| 654 case kMul: | 606 case ots::kMul: |
| 655 // TODO(yusukes): Should detect overflows. | 607 // TODO(yusukes): Should detect overflows. |
| 656 if (stack_size < 2) { | 608 if (stack_size < 2) { |
| 657 return OTS_FAILURE(); | 609 return OTS_FAILURE(); |
| 658 } | 610 } |
| 659 argument_stack->pop(); | 611 argument_stack->pop(); |
| 660 argument_stack->pop(); | 612 argument_stack->pop(); |
| 661 argument_stack->push(dummy_result); | 613 argument_stack->push(dummy_result); |
| 662 // TODO(yusukes): Implement this. We should push a real value for all | 614 // TODO(yusukes): Implement this. We should push a real value for all |
| 663 // arithmetic and conditional operations. | 615 // arithmetic and conditional operations. |
| 664 return true; | 616 return true; |
| 665 | 617 |
| 666 case kSqrt: | 618 case ots::kSqrt: |
| 667 // TODO(yusukes): Should check if the argument is negative. | 619 // TODO(yusukes): Should check if the argument is negative. |
| 668 if (stack_size < 1) { | 620 if (stack_size < 1) { |
| 669 return OTS_FAILURE(); | 621 return OTS_FAILURE(); |
| 670 } | 622 } |
| 671 argument_stack->pop(); | 623 argument_stack->pop(); |
| 672 argument_stack->push(dummy_result); | 624 argument_stack->push(dummy_result); |
| 673 // TODO(yusukes): Implement this. We should push a real value for all | 625 // TODO(yusukes): Implement this. We should push a real value for all |
| 674 // arithmetic and conditional operations. | 626 // arithmetic and conditional operations. |
| 675 return true; | 627 return true; |
| 676 | 628 |
| 677 case kDup: | 629 case ots::kDup: |
| 678 if (stack_size < 1) { | 630 if (stack_size < 1) { |
| 679 return OTS_FAILURE(); | 631 return OTS_FAILURE(); |
| 680 } | 632 } |
| 681 argument_stack->pop(); | 633 argument_stack->pop(); |
| 682 argument_stack->push(dummy_result); | 634 argument_stack->push(dummy_result); |
| 683 argument_stack->push(dummy_result); | 635 argument_stack->push(dummy_result); |
| 684 if (argument_stack->size() > kMaxArgumentStack) { | 636 if (argument_stack->size() > kMaxArgumentStack) { |
| 685 return OTS_FAILURE(); | 637 return OTS_FAILURE(); |
| 686 } | 638 } |
| 687 // TODO(yusukes): Implement this. We should push a real value for all | 639 // TODO(yusukes): Implement this. We should push a real value for all |
| 688 // arithmetic and conditional operations. | 640 // arithmetic and conditional operations. |
| 689 return true; | 641 return true; |
| 690 | 642 |
| 691 case kExch: | 643 case ots::kExch: |
| 692 if (stack_size < 2) { | 644 if (stack_size < 2) { |
| 693 return OTS_FAILURE(); | 645 return OTS_FAILURE(); |
| 694 } | 646 } |
| 695 argument_stack->pop(); | 647 argument_stack->pop(); |
| 696 argument_stack->pop(); | 648 argument_stack->pop(); |
| 697 argument_stack->push(dummy_result); | 649 argument_stack->push(dummy_result); |
| 698 argument_stack->push(dummy_result); | 650 argument_stack->push(dummy_result); |
| 699 // TODO(yusukes): Implement this. We should push a real value for all | 651 // TODO(yusukes): Implement this. We should push a real value for all |
| 700 // arithmetic and conditional operations. | 652 // arithmetic and conditional operations. |
| 701 return true; | 653 return true; |
| 702 | 654 |
| 703 case kHFlex: | 655 case ots::kHFlex: |
| 704 if (!(*in_out_found_width)) { | 656 if (!(*in_out_found_width)) { |
| 705 return OTS_FAILURE(); | 657 return OTS_FAILURE(); |
| 706 } | 658 } |
| 707 if (stack_size != 7) { | 659 if (stack_size != 7) { |
| 708 return OTS_FAILURE(); | 660 return OTS_FAILURE(); |
| 709 } | 661 } |
| 710 while (!argument_stack->empty()) | 662 while (!argument_stack->empty()) |
| 711 argument_stack->pop(); | 663 argument_stack->pop(); |
| 712 return true; | 664 return true; |
| 713 | 665 |
| 714 case kFlex: | 666 case ots::kFlex: |
| 715 if (!(*in_out_found_width)) { | 667 if (!(*in_out_found_width)) { |
| 716 return OTS_FAILURE(); | 668 return OTS_FAILURE(); |
| 717 } | 669 } |
| 718 if (stack_size != 13) { | 670 if (stack_size != 13) { |
| 719 return OTS_FAILURE(); | 671 return OTS_FAILURE(); |
| 720 } | 672 } |
| 721 while (!argument_stack->empty()) | 673 while (!argument_stack->empty()) |
| 722 argument_stack->pop(); | 674 argument_stack->pop(); |
| 723 return true; | 675 return true; |
| 724 | 676 |
| 725 case kHFlex1: | 677 case ots::kHFlex1: |
| 726 if (!(*in_out_found_width)) { | 678 if (!(*in_out_found_width)) { |
| 727 return OTS_FAILURE(); | 679 return OTS_FAILURE(); |
| 728 } | 680 } |
| 729 if (stack_size != 9) { | 681 if (stack_size != 9) { |
| 730 return OTS_FAILURE(); | 682 return OTS_FAILURE(); |
| 731 } | 683 } |
| 732 while (!argument_stack->empty()) | 684 while (!argument_stack->empty()) |
| 733 argument_stack->pop(); | 685 argument_stack->pop(); |
| 734 return true; | 686 return true; |
| 735 | 687 |
| 736 case kFlex1: | 688 case ots::kFlex1: |
| 737 if (!(*in_out_found_width)) { | 689 if (!(*in_out_found_width)) { |
| 738 return OTS_FAILURE(); | 690 return OTS_FAILURE(); |
| 739 } | 691 } |
| 740 if (stack_size != 11) { | 692 if (stack_size != 11) { |
| 741 return OTS_FAILURE(); | 693 return OTS_FAILURE(); |
| 742 } | 694 } |
| 743 while (!argument_stack->empty()) | 695 while (!argument_stack->empty()) |
| 744 argument_stack->pop(); | 696 argument_stack->pop(); |
| 745 return true; | 697 return true; |
| 746 } | 698 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 char_string, | 769 char_string, |
| 818 argument_stack, | 770 argument_stack, |
| 819 out_found_endchar, | 771 out_found_endchar, |
| 820 in_out_found_width, | 772 in_out_found_width, |
| 821 in_out_num_stems)) { | 773 in_out_num_stems)) { |
| 822 return OTS_FAILURE(); | 774 return OTS_FAILURE(); |
| 823 } | 775 } |
| 824 if (*out_found_endchar) { | 776 if (*out_found_endchar) { |
| 825 return true; | 777 return true; |
| 826 } | 778 } |
| 827 if (operator_or_operand == kReturn) { | 779 if (operator_or_operand == ots::kReturn) { |
| 828 return true; | 780 return true; |
| 829 } | 781 } |
| 830 } | 782 } |
| 831 | 783 |
| 832 // No endchar operator is found. | 784 // No endchar operator is found. |
| 833 return OTS_FAILURE(); | 785 return OTS_FAILURE(); |
| 834 } | 786 } |
| 835 | 787 |
| 836 // Selects a set of subroutings for |glyph_index| from |cff| and sets it on | 788 // Selects a set of subroutings for |glyph_index| from |cff| and sets it on |
| 837 // |out_local_subrs_to_use|. Returns true on success. | 789 // |out_local_subrs_to_use|. Returns true on success. |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 std::stack<int32_t> argument_stack; | 872 std::stack<int32_t> argument_stack; |
| 921 bool found_endchar = false; | 873 bool found_endchar = false; |
| 922 bool found_width = false; | 874 bool found_width = false; |
| 923 size_t num_stems = 0; | 875 size_t num_stems = 0; |
| 924 if (!ExecuteType2CharString(0 /* initial call_depth is zero */, | 876 if (!ExecuteType2CharString(0 /* initial call_depth is zero */, |
| 925 global_subrs_index, *local_subrs_to_use, | 877 global_subrs_index, *local_subrs_to_use, |
| 926 cff_table, &char_string, &argument_stack, | 878 cff_table, &char_string, &argument_stack, |
| 927 &found_endchar, &found_width, &num_stems)) { | 879 &found_endchar, &found_width, &num_stems)) { |
| 928 return OTS_FAILURE(); | 880 return OTS_FAILURE(); |
| 929 } | 881 } |
| 882 if (!found_endchar) { |
| 883 return OTS_FAILURE(); |
| 884 } |
| 930 } | 885 } |
| 931 return true; | 886 return true; |
| 932 } | 887 } |
| 933 | 888 |
| 934 } // namespace ots | 889 } // namespace ots |
| OLD | NEW |