gfx/graphite2/src/inc/opcodes.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* GRAPHITE2 LICENSING
michael@0 2
michael@0 3 Copyright 2010, SIL International
michael@0 4 All rights reserved.
michael@0 5
michael@0 6 This library is free software; you can redistribute it and/or modify
michael@0 7 it under the terms of the GNU Lesser General Public License as published
michael@0 8 by the Free Software Foundation; either version 2.1 of License, or
michael@0 9 (at your option) any later version.
michael@0 10
michael@0 11 This program is distributed in the hope that it will be useful,
michael@0 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
michael@0 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
michael@0 14 Lesser General Public License for more details.
michael@0 15
michael@0 16 You should also have received a copy of the GNU Lesser General Public
michael@0 17 License along with this library in the file named "LICENSE".
michael@0 18 If not, write to the Free Software Foundation, 51 Franklin Street,
michael@0 19 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
michael@0 20 internet at http://www.fsf.org/licenses/lgpl.html.
michael@0 21
michael@0 22 Alternatively, the contents of this file may be used under the terms of the
michael@0 23 Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
michael@0 24 License, as published by the Free Software Foundation, either version 2
michael@0 25 of the License or (at your option) any later version.
michael@0 26 */
michael@0 27 #pragma once
michael@0 28 // This file will be pulled into and integrated into a machine implmentation
michael@0 29 // DO NOT build directly and under no circumstances every #include headers in
michael@0 30 // here or you will break the direct_machine.
michael@0 31 //
michael@0 32 // Implementers' notes
michael@0 33 // ==================
michael@0 34 // You have access to a few primitives and the full C++ code:
michael@0 35 // declare_params(n) Tells the interpreter how many bytes of parameter
michael@0 36 // space to claim for this instruction uses and
michael@0 37 // initialises the param pointer. You *must* before the
michael@0 38 // first use of param.
michael@0 39 // use_params(n) Claim n extra bytes of param space beyond what was
michael@0 40 // claimed using delcare_param.
michael@0 41 // param A const byte pointer for the parameter space claimed by
michael@0 42 // this instruction.
michael@0 43 // binop(op) Implement a binary operation on the stack using the
michael@0 44 // specified C++ operator.
michael@0 45 // NOT_IMPLEMENTED Any instruction body containing this will exit the
michael@0 46 // program with an assertion error. Instructions that are
michael@0 47 // not implemented should also be marked NILOP in the
michael@0 48 // opcodes tables this will cause the code class to spot
michael@0 49 // them in a live code stream and throw a runtime_error
michael@0 50 // instead.
michael@0 51 // push(n) Push the value n onto the stack.
michael@0 52 // pop() Pop the top most value and return it.
michael@0 53 //
michael@0 54 // You have access to the following named fast 'registers':
michael@0 55 // sp = The pointer to the current top of stack, the last value
michael@0 56 // pushed.
michael@0 57 // seg = A reference to the Segment this code is running over.
michael@0 58 // is = The current slot index
michael@0 59 // isb = The original base slot index at the start of this rule
michael@0 60 // isf = The first positioned slot
michael@0 61 // isl = The last positioned slot
michael@0 62 // ip = The current instruction pointer
michael@0 63 // endPos = Position of advance of last cluster
michael@0 64
michael@0 65
michael@0 66 // #define NOT_IMPLEMENTED assert(false)
michael@0 67 #define NOT_IMPLEMENTED
michael@0 68
michael@0 69 #define binop(op) const int32 a = pop(); *sp = int32(*sp) op a
michael@0 70 #define use_params(n) dp += n
michael@0 71
michael@0 72 #define declare_params(n) const byte * param = dp; \
michael@0 73 use_params(n);
michael@0 74
michael@0 75 #define push(n) { *++sp = n; }
michael@0 76 #define pop() (*sp--)
michael@0 77 #define slotat(x) (map[(x)])
michael@0 78 #define DIE { is=seg.last(); EXIT(1); }
michael@0 79 #define POSITIONED 1
michael@0 80
michael@0 81 STARTOP(nop)
michael@0 82 do {} while (0);
michael@0 83 ENDOP
michael@0 84
michael@0 85 STARTOP(push_byte)
michael@0 86 declare_params(1);
michael@0 87 push(int8(*param));
michael@0 88 ENDOP
michael@0 89
michael@0 90 STARTOP(push_byte_u)
michael@0 91 declare_params(1);
michael@0 92 push(uint8(*param));
michael@0 93 ENDOP
michael@0 94
michael@0 95 STARTOP(push_short)
michael@0 96 declare_params(2);
michael@0 97 const int16 r = int16(param[0]) << 8
michael@0 98 | uint8(param[1]);
michael@0 99 push(r);
michael@0 100 ENDOP
michael@0 101
michael@0 102 STARTOP(push_short_u)
michael@0 103 declare_params(2);
michael@0 104 const uint16 r = uint16(param[0]) << 8
michael@0 105 | uint8(param[1]);
michael@0 106 push(r);
michael@0 107 ENDOP
michael@0 108
michael@0 109 STARTOP(push_long)
michael@0 110 declare_params(4);
michael@0 111 const int32 r = int32(param[0]) << 24
michael@0 112 | uint32(param[1]) << 16
michael@0 113 | uint32(param[2]) << 8
michael@0 114 | uint8(param[3]);
michael@0 115 push(r);
michael@0 116 ENDOP
michael@0 117
michael@0 118 STARTOP(add)
michael@0 119 binop(+);
michael@0 120 ENDOP
michael@0 121
michael@0 122 STARTOP(sub)
michael@0 123 binop(-);
michael@0 124 ENDOP
michael@0 125
michael@0 126 STARTOP(mul)
michael@0 127 binop(*);
michael@0 128 ENDOP
michael@0 129
michael@0 130 STARTOP(div_)
michael@0 131 if (*sp == 0) DIE;
michael@0 132 binop(/);
michael@0 133 ENDOP
michael@0 134
michael@0 135 STARTOP(min_)
michael@0 136 const int32 a = pop(), b = *sp;
michael@0 137 if (a < b) *sp = a;
michael@0 138 ENDOP
michael@0 139
michael@0 140 STARTOP(max_)
michael@0 141 const int32 a = pop(), b = *sp;
michael@0 142 if (a > b) *sp = a;
michael@0 143 ENDOP
michael@0 144
michael@0 145 STARTOP(neg)
michael@0 146 *sp = uint32(-int32(*sp));
michael@0 147 ENDOP
michael@0 148
michael@0 149 STARTOP(trunc8)
michael@0 150 *sp = uint8(*sp);
michael@0 151 ENDOP
michael@0 152
michael@0 153 STARTOP(trunc16)
michael@0 154 *sp = uint16(*sp);
michael@0 155 ENDOP
michael@0 156
michael@0 157 STARTOP(cond)
michael@0 158 const uint32 f = pop(), t = pop(), c = pop();
michael@0 159 push(c ? t : f);
michael@0 160 ENDOP
michael@0 161
michael@0 162 STARTOP(and_)
michael@0 163 binop(&&);
michael@0 164 ENDOP
michael@0 165
michael@0 166 STARTOP(or_)
michael@0 167 binop(||);
michael@0 168 ENDOP
michael@0 169
michael@0 170 STARTOP(not_)
michael@0 171 *sp = !*sp;
michael@0 172 ENDOP
michael@0 173
michael@0 174 STARTOP(equal)
michael@0 175 binop(==);
michael@0 176 ENDOP
michael@0 177
michael@0 178 STARTOP(not_eq_)
michael@0 179 binop(!=);
michael@0 180 ENDOP
michael@0 181
michael@0 182 STARTOP(less)
michael@0 183 binop(<);
michael@0 184 ENDOP
michael@0 185
michael@0 186 STARTOP(gtr)
michael@0 187 binop(>);
michael@0 188 ENDOP
michael@0 189
michael@0 190 STARTOP(less_eq)
michael@0 191 binop(<=);
michael@0 192 ENDOP
michael@0 193
michael@0 194 STARTOP(gtr_eq)
michael@0 195 binop(>=);
michael@0 196 ENDOP
michael@0 197
michael@0 198 STARTOP(next)
michael@0 199 if (map - &smap[0] >= int(smap.size())) DIE
michael@0 200 if (is)
michael@0 201 {
michael@0 202 if (is == smap.highwater())
michael@0 203 smap.highpassed(true);
michael@0 204 is = is->next();
michael@0 205 }
michael@0 206 ++map;
michael@0 207 ENDOP
michael@0 208
michael@0 209 STARTOP(next_n)
michael@0 210 use_params(1);
michael@0 211 NOT_IMPLEMENTED;
michael@0 212 //declare_params(1);
michael@0 213 //const size_t num = uint8(*param);
michael@0 214 ENDOP
michael@0 215
michael@0 216 //STARTOP(copy_next)
michael@0 217 // if (is) is = is->next();
michael@0 218 // ++map;
michael@0 219 // ENDOP
michael@0 220
michael@0 221 STARTOP(put_glyph_8bit_obs)
michael@0 222 declare_params(1);
michael@0 223 const unsigned int output_class = uint8(*param);
michael@0 224 is->setGlyph(&seg, seg.getClassGlyph(output_class, 0));
michael@0 225 ENDOP
michael@0 226
michael@0 227 STARTOP(put_subs_8bit_obs)
michael@0 228 declare_params(3);
michael@0 229 const int slot_ref = int8(param[0]);
michael@0 230 const unsigned int input_class = uint8(param[1]),
michael@0 231 output_class = uint8(param[2]);
michael@0 232 uint16 index;
michael@0 233 slotref slot = slotat(slot_ref);
michael@0 234 if (slot)
michael@0 235 {
michael@0 236 index = seg.findClassIndex(input_class, slot->gid());
michael@0 237 is->setGlyph(&seg, seg.getClassGlyph(output_class, index));
michael@0 238 }
michael@0 239 ENDOP
michael@0 240
michael@0 241 STARTOP(put_copy)
michael@0 242 declare_params(1);
michael@0 243 const int slot_ref = int8(*param);
michael@0 244 if (is && (slot_ref ||is != *map))
michael@0 245 {
michael@0 246 int16 *tempUserAttrs = is->userAttrs();
michael@0 247 slotref ref = slotat(slot_ref);
michael@0 248 if (ref)
michael@0 249 {
michael@0 250 memcpy(tempUserAttrs, ref->userAttrs(), seg.numAttrs() * sizeof(uint16));
michael@0 251 Slot *prev = is->prev();
michael@0 252 Slot *next = is->next();
michael@0 253 memcpy(is, slotat(slot_ref), sizeof(Slot));
michael@0 254 is->userAttrs(tempUserAttrs);
michael@0 255 is->next(next);
michael@0 256 is->prev(prev);
michael@0 257 is->sibling(NULL);
michael@0 258 }
michael@0 259 is->markCopied(false);
michael@0 260 is->markDeleted(false);
michael@0 261 }
michael@0 262 ENDOP
michael@0 263
michael@0 264 STARTOP(insert)
michael@0 265 Slot *newSlot = seg.newSlot();
michael@0 266 if (!newSlot) DIE;
michael@0 267 Slot *iss = is;
michael@0 268 while (iss && iss->isDeleted()) iss = iss->next();
michael@0 269 if (!iss)
michael@0 270 {
michael@0 271 if (seg.last())
michael@0 272 {
michael@0 273 seg.last()->next(newSlot);
michael@0 274 newSlot->prev(seg.last());
michael@0 275 newSlot->before(seg.last()->before());
michael@0 276 seg.last(newSlot);
michael@0 277 }
michael@0 278 else
michael@0 279 {
michael@0 280 seg.first(newSlot);
michael@0 281 seg.last(newSlot);
michael@0 282 }
michael@0 283 }
michael@0 284 else if (iss->prev())
michael@0 285 {
michael@0 286 iss->prev()->next(newSlot);
michael@0 287 newSlot->prev(iss->prev());
michael@0 288 newSlot->before(iss->prev()->after());
michael@0 289 }
michael@0 290 else
michael@0 291 {
michael@0 292 newSlot->prev(NULL);
michael@0 293 newSlot->before(iss->before());
michael@0 294 seg.first(newSlot);
michael@0 295 }
michael@0 296 newSlot->next(iss);
michael@0 297 if (iss)
michael@0 298 {
michael@0 299 iss->prev(newSlot);
michael@0 300 newSlot->originate(iss->original());
michael@0 301 newSlot->after(iss->before());
michael@0 302 }
michael@0 303 else if (newSlot->prev())
michael@0 304 {
michael@0 305 newSlot->originate(newSlot->prev()->original());
michael@0 306 newSlot->after(newSlot->prev()->after());
michael@0 307 }
michael@0 308 else
michael@0 309 {
michael@0 310 newSlot->originate(seg.defaultOriginal());
michael@0 311 }
michael@0 312 is = newSlot;
michael@0 313 seg.extendLength(1);
michael@0 314 if (map != &smap[-1])
michael@0 315 --map;
michael@0 316 ENDOP
michael@0 317
michael@0 318 STARTOP(delete_)
michael@0 319 if (!is) DIE
michael@0 320 is->markDeleted(true);
michael@0 321 if (is->prev())
michael@0 322 is->prev()->next(is->next());
michael@0 323 else
michael@0 324 seg.first(is->next());
michael@0 325
michael@0 326 if (is->next())
michael@0 327 is->next()->prev(is->prev());
michael@0 328 else
michael@0 329 seg.last(is->prev());
michael@0 330
michael@0 331 if (is == smap.highwater())
michael@0 332 smap.highwater(is->next());
michael@0 333 if (is->prev())
michael@0 334 is = is->prev();
michael@0 335 seg.extendLength(-1);
michael@0 336 ENDOP
michael@0 337
michael@0 338 STARTOP(assoc)
michael@0 339 declare_params(1);
michael@0 340 unsigned int num = uint8(*param);
michael@0 341 const int8 * assocs = reinterpret_cast<const int8 *>(param+1);
michael@0 342 use_params(num);
michael@0 343 int max = -1;
michael@0 344 int min = -1;
michael@0 345
michael@0 346 while (num-- > 0)
michael@0 347 {
michael@0 348 int sr = *assocs++;
michael@0 349 slotref ts = slotat(sr);
michael@0 350 if (ts && (min == -1 || ts->before() < min)) min = ts->before();
michael@0 351 if (ts && ts->after() > max) max = ts->after();
michael@0 352 }
michael@0 353 if (min > -1) // implies max > -1
michael@0 354 {
michael@0 355 is->before(min);
michael@0 356 is->after(max);
michael@0 357 }
michael@0 358 ENDOP
michael@0 359
michael@0 360 STARTOP(cntxt_item)
michael@0 361 // It turns out this is a cunningly disguised condition forward jump.
michael@0 362 declare_params(3);
michael@0 363 const int is_arg = int8(param[0]);
michael@0 364 const size_t iskip = uint8(param[1]),
michael@0 365 dskip = uint8(param[2]);
michael@0 366
michael@0 367 if (mapb + is_arg != map)
michael@0 368 {
michael@0 369 ip += iskip;
michael@0 370 dp += dskip;
michael@0 371 push(true);
michael@0 372 }
michael@0 373 ENDOP
michael@0 374
michael@0 375 STARTOP(attr_set)
michael@0 376 declare_params(1);
michael@0 377 const attrCode slat = attrCode(uint8(*param));
michael@0 378 const int val = int(pop());
michael@0 379 is->setAttr(&seg, slat, 0, val, smap);
michael@0 380 ENDOP
michael@0 381
michael@0 382 STARTOP(attr_add)
michael@0 383 declare_params(1);
michael@0 384 const attrCode slat = attrCode(uint8(*param));
michael@0 385 const int val = int(pop());
michael@0 386 if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
michael@0 387 {
michael@0 388 seg.positionSlots(0, *smap.begin(), *(smap.end()-1));
michael@0 389 flags |= POSITIONED;
michael@0 390 }
michael@0 391 int res = is->getAttr(&seg, slat, 0);
michael@0 392 is->setAttr(&seg, slat, 0, val + res, smap);
michael@0 393 ENDOP
michael@0 394
michael@0 395 STARTOP(attr_sub)
michael@0 396 declare_params(1);
michael@0 397 const attrCode slat = attrCode(uint8(*param));
michael@0 398 const int val = int(pop());
michael@0 399 if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
michael@0 400 {
michael@0 401 seg.positionSlots(0, *smap.begin(), *(smap.end()-1));
michael@0 402 flags |= POSITIONED;
michael@0 403 }
michael@0 404 int res = is->getAttr(&seg, slat, 0);
michael@0 405 is->setAttr(&seg, slat, 0, res - val, smap);
michael@0 406 ENDOP
michael@0 407
michael@0 408 STARTOP(attr_set_slot)
michael@0 409 declare_params(1);
michael@0 410 const attrCode slat = attrCode(uint8(*param));
michael@0 411 const int offset = (map - smap.begin())*int(slat == gr_slatAttTo);
michael@0 412 const int val = int(pop()) + offset;
michael@0 413 is->setAttr(&seg, slat, offset, val, smap);
michael@0 414 ENDOP
michael@0 415
michael@0 416 STARTOP(iattr_set_slot)
michael@0 417 declare_params(2);
michael@0 418 const attrCode slat = attrCode(uint8(param[0]));
michael@0 419 const size_t idx = uint8(param[1]);
michael@0 420 const int val = int(pop()) + (map - smap.begin())*int(slat == gr_slatAttTo);
michael@0 421 is->setAttr(&seg, slat, idx, val, smap);
michael@0 422 ENDOP
michael@0 423
michael@0 424 STARTOP(push_slot_attr)
michael@0 425 declare_params(2);
michael@0 426 const attrCode slat = attrCode(uint8(param[0]));
michael@0 427 const int slot_ref = int8(param[1]);
michael@0 428 if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
michael@0 429 {
michael@0 430 seg.positionSlots(0, *smap.begin(), *(smap.end()-1));
michael@0 431 flags |= POSITIONED;
michael@0 432 }
michael@0 433 slotref slot = slotat(slot_ref);
michael@0 434 if (slot)
michael@0 435 {
michael@0 436 int res = slot->getAttr(&seg, slat, 0);
michael@0 437 push(res);
michael@0 438 }
michael@0 439 ENDOP
michael@0 440
michael@0 441 STARTOP(push_glyph_attr_obs)
michael@0 442 declare_params(2);
michael@0 443 const unsigned int glyph_attr = uint8(param[0]);
michael@0 444 const int slot_ref = int8(param[1]);
michael@0 445 slotref slot = slotat(slot_ref);
michael@0 446 if (slot)
michael@0 447 push(int32(seg.glyphAttr(slot->gid(), glyph_attr)));
michael@0 448 ENDOP
michael@0 449
michael@0 450 STARTOP(push_glyph_metric)
michael@0 451 declare_params(3);
michael@0 452 const unsigned int glyph_attr = uint8(param[0]);
michael@0 453 const int slot_ref = int8(param[1]);
michael@0 454 const signed int attr_level = uint8(param[2]);
michael@0 455 slotref slot = slotat(slot_ref);
michael@0 456 if (slot)
michael@0 457 push(seg.getGlyphMetric(slot, glyph_attr, attr_level));
michael@0 458 ENDOP
michael@0 459
michael@0 460 STARTOP(push_feat)
michael@0 461 declare_params(2);
michael@0 462 const unsigned int feat = uint8(param[0]);
michael@0 463 const int slot_ref = int8(param[1]);
michael@0 464 slotref slot = slotat(slot_ref);
michael@0 465 if (slot)
michael@0 466 {
michael@0 467 uint8 fid = seg.charinfo(slot->original())->fid();
michael@0 468 push(seg.getFeature(fid, feat));
michael@0 469 }
michael@0 470 ENDOP
michael@0 471
michael@0 472 STARTOP(push_att_to_gattr_obs)
michael@0 473 declare_params(2);
michael@0 474 const unsigned int glyph_attr = uint8(param[0]);
michael@0 475 const int slot_ref = int8(param[1]);
michael@0 476 slotref slot = slotat(slot_ref);
michael@0 477 if (slot)
michael@0 478 {
michael@0 479 slotref att = slot->attachedTo();
michael@0 480 if (att) slot = att;
michael@0 481 push(int32(seg.glyphAttr(slot->gid(), glyph_attr)));
michael@0 482 }
michael@0 483 ENDOP
michael@0 484
michael@0 485 STARTOP(push_att_to_glyph_metric)
michael@0 486 declare_params(3);
michael@0 487 const unsigned int glyph_attr = uint8(param[0]);
michael@0 488 const int slot_ref = int8(param[1]);
michael@0 489 const signed int attr_level = uint8(param[2]);
michael@0 490 slotref slot = slotat(slot_ref);
michael@0 491 if (slot)
michael@0 492 {
michael@0 493 slotref att = slot->attachedTo();
michael@0 494 if (att) slot = att;
michael@0 495 push(int32(seg.getGlyphMetric(slot, glyph_attr, attr_level)));
michael@0 496 }
michael@0 497 ENDOP
michael@0 498
michael@0 499 STARTOP(push_islot_attr)
michael@0 500 declare_params(3);
michael@0 501 const attrCode slat = attrCode(uint8(param[0]));
michael@0 502 const int slot_ref = int8(param[1]),
michael@0 503 idx = uint8(param[2]);
michael@0 504 if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
michael@0 505 {
michael@0 506 seg.positionSlots(0, *smap.begin(), *(smap.end()-1));
michael@0 507 flags |= POSITIONED;
michael@0 508 }
michael@0 509 slotref slot = slotat(slot_ref);
michael@0 510 if (slot)
michael@0 511 {
michael@0 512 int res = slot->getAttr(&seg, slat, idx);
michael@0 513 push(res);
michael@0 514 }
michael@0 515 ENDOP
michael@0 516
michael@0 517 #if 0
michael@0 518 STARTOP(push_iglyph_attr) // not implemented
michael@0 519 NOT_IMPLEMENTED;
michael@0 520 ENDOP
michael@0 521 #endif
michael@0 522
michael@0 523 STARTOP(pop_ret)
michael@0 524 const uint32 ret = pop();
michael@0 525 EXIT(ret);
michael@0 526 ENDOP
michael@0 527
michael@0 528 STARTOP(ret_zero)
michael@0 529 EXIT(0);
michael@0 530 ENDOP
michael@0 531
michael@0 532 STARTOP(ret_true)
michael@0 533 EXIT(1);
michael@0 534 ENDOP
michael@0 535
michael@0 536 STARTOP(iattr_set)
michael@0 537 declare_params(2);
michael@0 538 const attrCode slat = attrCode(uint8(param[0]));
michael@0 539 const size_t idx = uint8(param[1]);
michael@0 540 const int val = int(pop());
michael@0 541 is->setAttr(&seg, slat, idx, val, smap);
michael@0 542 ENDOP
michael@0 543
michael@0 544 STARTOP(iattr_add)
michael@0 545 declare_params(2);
michael@0 546 const attrCode slat = attrCode(uint8(param[0]));
michael@0 547 const size_t idx = uint8(param[1]);
michael@0 548 const int val = int(pop());
michael@0 549 if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
michael@0 550 {
michael@0 551 seg.positionSlots(0, *smap.begin(), *(smap.end()-1));
michael@0 552 flags |= POSITIONED;
michael@0 553 }
michael@0 554 int res = is->getAttr(&seg, slat, idx);
michael@0 555 is->setAttr(&seg, slat, idx, val + res, smap);
michael@0 556 ENDOP
michael@0 557
michael@0 558 STARTOP(iattr_sub)
michael@0 559 declare_params(2);
michael@0 560 const attrCode slat = attrCode(uint8(param[0]));
michael@0 561 const size_t idx = uint8(param[1]);
michael@0 562 const int val = int(pop());
michael@0 563 if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
michael@0 564 {
michael@0 565 seg.positionSlots(0, *smap.begin(), *(smap.end()-1));
michael@0 566 flags |= POSITIONED;
michael@0 567 }
michael@0 568 int res = is->getAttr(&seg, slat, idx);
michael@0 569 is->setAttr(&seg, slat, idx, res - val, smap);
michael@0 570 ENDOP
michael@0 571
michael@0 572 STARTOP(push_proc_state)
michael@0 573 use_params(1);
michael@0 574 push(1);
michael@0 575 ENDOP
michael@0 576
michael@0 577 STARTOP(push_version)
michael@0 578 push(0x00030000);
michael@0 579 ENDOP
michael@0 580
michael@0 581 STARTOP(put_subs)
michael@0 582 declare_params(5);
michael@0 583 const int slot_ref = int8(param[0]);
michael@0 584 const unsigned int input_class = uint8(param[1]) << 8
michael@0 585 | uint8(param[2]);
michael@0 586 const unsigned int output_class = uint8(param[3]) << 8
michael@0 587 | uint8(param[4]);
michael@0 588 slotref slot = slotat(slot_ref);
michael@0 589 if (slot)
michael@0 590 {
michael@0 591 int index = seg.findClassIndex(input_class, slot->gid());
michael@0 592 is->setGlyph(&seg, seg.getClassGlyph(output_class, index));
michael@0 593 }
michael@0 594 ENDOP
michael@0 595
michael@0 596 #if 0
michael@0 597 STARTOP(put_subs2) // not implemented
michael@0 598 NOT_IMPLEMENTED;
michael@0 599 ENDOP
michael@0 600
michael@0 601 STARTOP(put_subs3) // not implemented
michael@0 602 NOT_IMPLEMENTED;
michael@0 603 ENDOP
michael@0 604 #endif
michael@0 605
michael@0 606 STARTOP(put_glyph)
michael@0 607 declare_params(2);
michael@0 608 const unsigned int output_class = uint8(param[0]) << 8
michael@0 609 | uint8(param[1]);
michael@0 610 is->setGlyph(&seg, seg.getClassGlyph(output_class, 0));
michael@0 611 ENDOP
michael@0 612
michael@0 613 STARTOP(push_glyph_attr)
michael@0 614 declare_params(3);
michael@0 615 const unsigned int glyph_attr = uint8(param[0]) << 8
michael@0 616 | uint8(param[1]);
michael@0 617 const int slot_ref = int8(param[2]);
michael@0 618 slotref slot = slotat(slot_ref);
michael@0 619 if (slot)
michael@0 620 push(int32(seg.glyphAttr(slot->gid(), glyph_attr)));
michael@0 621 ENDOP
michael@0 622
michael@0 623 STARTOP(push_att_to_glyph_attr)
michael@0 624 declare_params(3);
michael@0 625 const unsigned int glyph_attr = uint8(param[0]) << 8
michael@0 626 | uint8(param[1]);
michael@0 627 const int slot_ref = int8(param[2]);
michael@0 628 slotref slot = slotat(slot_ref);
michael@0 629 if (slot)
michael@0 630 {
michael@0 631 slotref att = slot->attachedTo();
michael@0 632 if (att) slot = att;
michael@0 633 push(int32(seg.glyphAttr(slot->gid(), glyph_attr)));
michael@0 634 }
michael@0 635 ENDOP
michael@0 636
michael@0 637 STARTOP(temp_copy)
michael@0 638 slotref newSlot = seg.newSlot();
michael@0 639 if (!newSlot) DIE;
michael@0 640 int16 *tempUserAttrs = newSlot->userAttrs();
michael@0 641 memcpy(newSlot, is, sizeof(Slot));
michael@0 642 memcpy(tempUserAttrs, is->userAttrs(), seg.numAttrs() * sizeof(uint16));
michael@0 643 newSlot->userAttrs(tempUserAttrs);
michael@0 644 newSlot->markCopied(true);
michael@0 645 *map = newSlot;
michael@0 646 ENDOP

mercurial