/* // Given an input string of characters and a location in which to start looking // calculate, using the state table, which one is the last character of the syllable // that starts in the starting position. */ static int myanmar_nextSyllableBoundary(const HB_UChar16 *s, int start, int end, HB_Bool *invalid) { const HB_UChar16 *uc = s + start; int state = 0; int pos = start; *invalid = FALSE; while (pos < end) { MymrCharClass charClass = getMyanmarCharClass(*uc); state = mymrStateTable[state][charClass & Mymr_CF_CLASS_MASK]; if (pos == start) *invalid = (HB_Bool)(charClass & Mymr_CF_DOTTED_CIRCLE); MMDEBUG("state[%d]=%d class=%8x (uc=%4x)", pos - start, state, charClass, *uc); if (state < 0) { if (state < -1) --pos; break; } ++uc; ++pos; } return pos; }
bool Track::Private::play(int _iterations) { /* sanity checks */ if (_iterations == 0) { MMDEBUG("Trying to play track with no iterations"); if (iterations) stop(); return(false); } else if (iterations) { MMERROR("Track already playing!"); return(false); } iterations = _iterations; skip_decode = false; codec->reset(); bsize = pcm->bufferSize(); buffer = new char[bsize]; update(); return(true); }
void Track::Private::update(void) { if (!buffer) return; /* sanity checks */ if (!pcm) { MMDEBUG("Trying to play on an invalid PCM, stopping!"); stop(); return; } if (!pcm->isOpen()) { MMDEBUG("Trying to play on a closed PCM, stopping!"); stop(); return; } /* stop check */ if (!skip_decode) { if (!iterations) { stop(); return; } memset(buffer, 0, bsize); size_t l_read = codec->read(buffer, bsize); /* * Reaching the end, check if we need to loop */ if (l_read < bsize && (iterations == -1 || --iterations)) { codec->reset(); l_read += codec->read(buffer + l_read, bsize - l_read); } bdecoded = l_read; } else skip_decode = false; skip_decode = !pcm->mix(buffer, bdecoded); }
void PCM::Close(Handle *pcm_handle) { assert(pcm_handle && "Tried to use invalid PCM device!"); assert(pcm_handle->buffer && "Buffer missing from PCM handle!"); delete[] pcm_handle->buffer, pcm_handle->buffer = 0; delete pcm_handle; MMDEBUG("Dummy PCM device closed."); }
/// @fn void termination_handler (int signum) /// @brief termination signal handler. /// @param[in] signum signal number /// @return none static void s_termination_handler (int signum) { switch (signum) { case SIGINT: case SIGHUP: case SIGTERM: MMDEBUG(ID_APP,"\nsig received[%d]\n",signum); g_interrupt=true; break; default: fprintf(stderr,"\ns_termination_handler: sig not handled[%d]\n",signum); break; } }
PCM::Handle * PCM::Open(uint32_t sample_rate, uint8_t bit_depth, uint8_t channels) { MMUNUSED(sample_rate); PCM::Handle *l_handle(new Handle); l_handle->buffer_size = (sample_rate/MARSHMALLOW_ENGINE_FRAMERATE) * (bit_depth/8) * channels; l_handle->buffer = new char[l_handle->buffer_size]; MMDEBUG("Dummy PCM device opened."); return(l_handle); }
HB_Bool HB_MyanmarShape(HB_ShaperItem *item) { HB_Bool openType = FALSE; unsigned short *logClusters = item->log_clusters; HB_ShaperItem syllable = *item; int first_glyph = 0; int sstart = item->item.pos; int end = sstart + item->item.length; int i = 0; assert(item->item.script == HB_Script_Myanmar); #ifndef NO_OPENTYPE openType = HB_SelectScript(item, myanmar_features); #endif MMDEBUG("myanmar_shape: from %d length %d", item->item.pos, item->item.length); while (sstart < end) { HB_Bool invalid; int send = myanmar_nextSyllableBoundary(item->string, sstart, end, &invalid); MMDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart, invalid ? "TRUE" : "FALSE"); syllable.item.pos = sstart; syllable.item.length = send-sstart; syllable.glyphs = item->glyphs + first_glyph; syllable.attributes = item->attributes + first_glyph; syllable.advances = item->advances + first_glyph; syllable.offsets = item->offsets + first_glyph; syllable.num_glyphs = item->num_glyphs - first_glyph; if (!myanmar_shape_syllable(openType, &syllable, invalid)) { MMDEBUG("syllable shaping failed, syllable requests %d glyphs", syllable.num_glyphs); item->num_glyphs += syllable.num_glyphs; return FALSE; } /* fix logcluster array */ MMDEBUG("syllable:"); for (i = first_glyph; i < first_glyph + (int)syllable.num_glyphs; ++i) MMDEBUG(" %d -> glyph %x", i, item->glyphs[i]); MMDEBUG(" logclusters:"); for (i = sstart; i < send; ++i) { MMDEBUG(" %d -> glyph %d", i, first_glyph); logClusters[i-item->item.pos] = first_glyph; } sstart = send; first_glyph += syllable.num_glyphs; } item->num_glyphs = first_glyph; return TRUE; }
MARSHMALLOW_NAMESPACE_USE static void SignalHandler(int signal, siginfo_t *siginfo, void *context) { MMUNUSED(signal); MMUNUSED(siginfo); MMUNUSED(context); if (!Event::EventManager::Instance()) { MMERROR("\n*** Unix system signal received. But can't queueing quit event message yet... Ignoring. ***\n"); return; } MMDEBUG("\n*** Unix system signal received. Queueing quit event message. ***\n"); Event::SharedEvent l_event = new Event::QuitEvent; Event::EventManager::Instance()->queue(l_event); }
static HB_Bool myanmar_shape_syllable(HB_Bool openType, HB_ShaperItem *item, HB_Bool invalid) { /* // MMDEBUG("\nsyllable from %d len %d, str='%s'", item->item.pos, item->item.length, // item->string->mid(item->from, item->length).toUtf8().data()); */ #ifndef NO_OPENTYPE const int availableGlyphs = item->num_glyphs; #endif const HB_UChar16 *uc = item->string + item->item.pos; int vowel_e = -1; int kinzi = -1; int medial_ra = -1; int base = -1; int i; int len = 0; unsigned short reordered[32]; unsigned char properties[32]; enum { AboveForm = 0x01, PreForm = 0x02, PostForm = 0x04, BelowForm = 0x08 }; HB_Bool lastWasVirama = FALSE; int basePos = -1; memset(properties, 0, 32*sizeof(unsigned char)); /* according to the table the max length of a syllable should be around 14 chars */ assert(item->item.length < 32); #ifdef MYANMAR_DEBUG printf("original:"); for (i = 0; i < (int)item->item.length; i++) { printf(" %d: %4x", i, uc[i]); } #endif for (i = 0; i < (int)item->item.length; ++i) { HB_UChar16 chr = uc[i]; if (chr == Mymr_C_VOWEL_E) { vowel_e = i; continue; } if (i == 0 && chr == Mymr_C_NGA && i + 2 < (int)item->item.length && uc[i+1] == Mymr_C_VIRAMA) { int mc = getMyanmarCharClass(uc[i+2]); /*MMDEBUG("maybe kinzi: mc=%x", mc);*/ if ((mc & Mymr_CF_CONSONANT) == Mymr_CF_CONSONANT) { kinzi = i; continue; } } if (base >= 0 && chr == Mymr_C_VIRAMA && i + 1 < (int)item->item.length && uc[i+1] == Mymr_C_RA) { medial_ra = i; continue; } if (base < 0) base = i; } MMDEBUG("\n base=%d, vowel_e=%d, kinzi=%d, medial_ra=%d", base, vowel_e, kinzi, medial_ra); /* write vowel_e if found */ if (vowel_e >= 0) { reordered[0] = Mymr_C_VOWEL_E; len = 1; } /* write medial_ra */ if (medial_ra >= 0) { reordered[len] = Mymr_C_VIRAMA; reordered[len+1] = Mymr_C_RA; properties[len] = PreForm; properties[len+1] = PreForm; len += 2; } /* shall we add a dotted circle? If in the position in which the base should be (first char in the string) there is a character that has the Dotted circle flag (a character that cannot be a base) then write a dotted circle */ if (invalid) { reordered[len] = C_DOTTED_CIRCLE; ++len; } /* copy the rest of the syllable to the output, inserting the kinzi at the correct place */ for (i = 0; i < (int)item->item.length; ++i) { hb_uint16 chr = uc[i]; MymrCharClass cc; if (i == vowel_e) continue; if (i == medial_ra || i == kinzi) { ++i; continue; } cc = getMyanmarCharClass(uc[i]); if (kinzi >= 0 && i > base && (cc & Mymr_CF_AFTER_KINZI)) { reordered[len] = Mymr_C_NGA; reordered[len+1] = Mymr_C_VIRAMA; if (len > 0) properties[len-1] = AboveForm; properties[len] = AboveForm; len += 2; kinzi = -1; } if (lastWasVirama) { int prop = 0; switch(cc & Mymr_CF_POS_MASK) { case Mymr_CF_POS_BEFORE: prop = PreForm; break; case Mymr_CF_POS_BELOW: prop = BelowForm; break; case Mymr_CF_POS_ABOVE: prop = AboveForm; break; case Mymr_CF_POS_AFTER: prop = PostForm; break; default: break; } properties[len-1] = prop; properties[len] = prop; if(basePos >= 0 && basePos == len-2) properties[len-2] = prop; } lastWasVirama = (chr == Mymr_C_VIRAMA); if(i == base) basePos = len; if ((chr != Mymr_C_SIGN_ZWNJ && chr != Mymr_C_SIGN_ZWJ) || !len) { reordered[len] = chr; ++len; } } if (kinzi >= 0) { reordered[len] = Mymr_C_NGA; reordered[len+1] = Mymr_C_VIRAMA; properties[len] = AboveForm; properties[len+1] = AboveForm; len += 2; } if (!item->font->klass->convertStringToGlyphIndices(item->font, reordered, len, item->glyphs, &item->num_glyphs, item->item.bidiLevel % 2)) return FALSE; MMDEBUG("after shaping: len=%d", len); for (i = 0; i < len; i++) { item->attributes[i].mark = FALSE; item->attributes[i].clusterStart = FALSE; item->attributes[i].justification = 0; item->attributes[i].zeroWidth = FALSE; MMDEBUG(" %d: %4x property=%x", i, reordered[i], properties[i]); } /* now we have the syllable in the right order, and can start running it through open type. */ #ifndef NO_OPENTYPE if (openType) { hb_uint32 where[32]; for (i = 0; i < len; ++i) { where[i] = ~(PreSubstProperty | BelowSubstProperty | AboveSubstProperty | PostSubstProperty | CligProperty | PositioningProperties); if (properties[i] & PreForm) where[i] &= ~PreFormProperty; if (properties[i] & BelowForm) where[i] &= ~BelowFormProperty; if (properties[i] & AboveForm) where[i] &= ~AboveFormProperty; if (properties[i] & PostForm) where[i] &= ~PostFormProperty; } HB_OpenTypeShape(item, where); if (!HB_OpenTypePosition(item, availableGlyphs, /*doLogClusters*/FALSE)) return FALSE; } else #endif { MMDEBUG("Not using openType"); HB_HeuristicPosition(item); } item->attributes[0].clusterStart = TRUE; return TRUE; }
/// @fn int s_trnc_state_machine(iow_socket_t *s, app_cfg_t *cfg) /// @brief state machine implementation /// @param[in] s iow_socket_t reference /// @param[in] cfg app_cfg reference /// @return none static int s_trnc_state_machine(iow_socket_t *s, app_cfg_t *cfg) { int retval=-1; int scycles=cfg->cycles; int trn_tx_count=0; int trn_rx_count=0; int trn_tx_bytes=0; int trn_rx_bytes=0; int trn_msg_count=0; int trn_msg_bytes=0; const char *reqstr="REQ\0"; if (NULL!=s) { // initialize variables trn_message_t message; trn_message_t *pmessage = &message; mbtrn_header_t *pheader = &pmessage->data.header; mbtrn_sounding_t *psounding = &pmessage->data.sounding; memset(pmessage,0,sizeof(message)); int hbeat_counter=0; int64_t test=0; byte *pread=NULL; uint32_t readlen=0; trnc_state_t state=ST_INIT; trnc_action_t action=AT_NOP; // state machine entry point while (state != ST_DONE && !g_interrupt) { // check states, assign actions switch (state) { case ST_INIT: memset(&message,0,MBTRN_MAX_MSG_BYTES); action = AT_CONNECT; break; case ST_CONNECTED: action=AT_WR_REQ; break; case ST_REQ_PENDING: case ST_SUBSCRIBED: memset(&message,0,MBTRN_MAX_MSG_BYTES); action=AT_RD_MSG; break; case ST_HBEAT_EXPIRED: action=AT_WR_REQ; break; default: break; }// switch // action: connect if (action == AT_CONNECT) { MMDEBUG(ID_APP,"connecting [%s:%d]\n",cfg->host,cfg->port); if( (test=iow_connect(s))==0 ) { MMDEBUG(ID_APP,"connect OK\n"); state=ST_CONNECTED; }else{ MERROR("connect failed [%"PRId64"]\n",test); } } // action: write request if (action == AT_WR_REQ) { test=iow_sendto(s,NULL,(byte *)reqstr,4,0); MMDEBUG(ID_APP,"sendto REQ ret[%"PRId64"] [%d/%s]\n",test,errno,strerror(errno)); if( test>0 ){ trn_tx_count++; trn_tx_bytes+=test; state=ST_REQ_PENDING; }else{ MMDEBUG(ID_APP,"sendto failed ret[%"PRId64"] [%d/%s]\n",test,errno,strerror(errno)); } } // action: read response if (action == AT_RD_MSG) { pread = (byte *)&message; readlen = MBTRN_MAX_MSG_BYTES; // request message if ((test = iow_recvfrom(s, NULL, pread, readlen))>0) { trn_rx_bytes+=test; trn_rx_count++; // check message type if (pheader->type==MBTRN_MSGTYPE_ACK) { MMDEBUG(ID_APP,"received ACK ret[%"PRId64"] [%08X]\n",test,pheader->type); hbeat_counter=0; state=ST_SUBSCRIBED; }else if (pheader->type==MBTRN_MSGTYPE_MB1) { MMDEBUG(ID_APP,"received MSG ret[%"PRId64"] type[%08X] size[%d] ping[%06d]\n",test,pheader->type,pheader->size,psounding->ping_number); trn_msg_count++; trn_msg_bytes+=test; action=AT_SHOW_MSG; if (state==ST_REQ_PENDING) { state=ST_REQ_PENDING; }else{ state=ST_SUBSCRIBED; } hbeat_counter++; MMDEBUG(ID_APP,"hbeat[%d/%d]\n",hbeat_counter,cfg->hbeat); if ( (hbeat_counter!=0) && (hbeat_counter%cfg->hbeat==0)) { state=ST_HBEAT_EXPIRED; } }else{ // response not recognized MMDEBUG(ID_APP,"invalid message [%08X]\n",pheader->type); } }else{ // read returned error // MMDEBUG(ID_APP,"invalid message [%d]\n",test); switch (errno) { case EWOULDBLOCK: // nothing to read // MMDEBUG(ID_APP,"err - [%d/%s]\n",errno, strerror(errno)); break; case ENOTCONN: case ECONNREFUSED: // host disconnected MMDEBUG(ID_APP,"err - server not connected [%d/%s]\n",errno, strerror(errno)); iow_socket_destroy(&s); s = iow_socket_new(cfg->host, cfg->port, ST_UDP); iow_set_blocking(s,(cfg->blocking==0?false:true)); sleep(5); state=ST_INIT; retval=-1; break; default: MMDEBUG(ID_APP,"err ? [%d/%s]\n",errno, strerror(errno)); break; }//switch } } // action: show message if (action == AT_SHOW_MSG) { MMDEBUG(ID_APP,"\nts[%.3f] ping[%06d] lat[%.4lf] lon[%.4lf]\nsd[%7.2lf] hdg[%6.2lf] nb[%03"PRIu32"]\n", psounding->ts, psounding->ping_number, psounding->lat, psounding->lon, psounding->depth, psounding->hdg, (uint32_t)psounding->nbeams); uint32_t j=0; struct mbtrn_beam_data *bd=psounding->beams; for (j=0; j<psounding->nbeams; j++,bd++){ MMDEBUG(ID_APP,"n[%03"PRIu32"] atrk/X[% 10.3lf] ctrk/Y[% 10.3lf] dpth/Z[% 10.3lf]\n", (uint32_t)bd->beam_num, bd->rhox, bd->rhoy, bd->rhoz); } } // action: quit state machine if (action == AT_QUIT) { break; } // check cycles and signals scycles--; if(scycles==0){ MTRACE(); retval=0; state=ST_DONE; } if(g_interrupt){ MTRACE(); retval=-1; state=ST_DONE; } }// while !ST_DONE }//else invalid arg MMINFO(ID_APP,"tx count/bytes[%d/%d]\n",trn_tx_count,trn_tx_bytes); MMINFO(ID_APP,"rx count/bytes[%d/%d]\n",trn_rx_count,trn_rx_bytes); MMINFO(ID_APP,"trn count/bytes[%d/%d]\n",trn_msg_count,trn_msg_bytes); return retval; }
/// @fn void parse_args(int argc, char ** argv, app_cfg_t * cfg) /// @brief parse command line args, set application configuration. /// @param[in] argc number of arguments /// @param[in] argv array of command line arguments (strings) /// @param[in] cfg application config structure /// @return none void parse_args(int argc, char **argv, app_cfg_t *cfg) { extern char WIN_DECLSPEC *optarg; int option_index; int c; bool help=false; bool version=false; static struct option options[] = { {"verbose", required_argument, NULL, 0}, {"help", no_argument, NULL, 0}, {"version", no_argument, NULL, 0}, {"host", required_argument, NULL, 0}, {"hbeat", required_argument, NULL, 0}, {"blocking", required_argument, NULL, 0}, {"cycles", required_argument, NULL, 0}, {"bsize", required_argument, NULL, 0}, {NULL, 0, NULL, 0}}; // process argument list while ((c = getopt_long(argc, argv, "", options, &option_index)) != -1){ switch (c) { // long options all return c=0 case 0: // verbose if (strcmp("verbose", options[option_index].name) == 0) { sscanf(optarg,"%d",&cfg->verbose); } // help else if (strcmp("help", options[option_index].name) == 0) { help = true; } // version else if (strcmp("version", options[option_index].name) == 0) { version = true; } // host else if (strcmp("host", options[option_index].name) == 0) { char *hsave=cfg->host; char *ocopy=strdup(optarg); cfg->host=strtok(ocopy,":"); if (cfg->host==NULL) { cfg->host=TRNC_HOST_DFL; } char *ip = strtok(NULL,":"); if (ip!=NULL) { sscanf(ip,"%d",&cfg->port); } // don't free ocopy here if(hsave!=NULL){ free(hsave); } } // blocking else if (strcmp("blocking", options[option_index].name) == 0) { sscanf(optarg,"%d",&cfg->blocking); } // hbeat else if (strcmp("hbeat", options[option_index].name) == 0) { sscanf(optarg,"%d",&cfg->hbeat); } // cycles else if (strcmp("cycles", options[option_index].name) == 0) { sscanf(optarg,"%d",&cfg->cycles); } // buffer size else if (strcmp("bsize", options[option_index].name) == 0) { sscanf(optarg,"%u",&cfg->bsize); cfg->bsize = (cfg->bsize>0 ? cfg->bsize : TRNC_BUF_LEN); } break; default: help=true; break; } if (version) { mbtrn_show_app_version(TRNC_NAME,TRNC_BUILD); exit(0); } if (help) { mbtrn_show_app_version(TRNC_NAME,TRNC_BUILD); s_show_help(); exit(0); } }// while // configure debug output switch (cfg->verbose) { case 0: mdb_set(ID_APP,MDL_INFO); break; case 1: mdb_set(ID_APP,MDL_DEBUG); break; case 2: mdb_set(ID_APP,MDL_DEBUG); mdb_set(ID_APP2,MDL_DEBUG); break; case 3: mdb_set(ID_APP,MDL_DEBUG); mdb_set(ID_APP2,MDL_DEBUG); mdb_set(ID_APP3,MDL_DEBUG); break; default: mdb_set(ID_APP,MDL_ERROR); break; } MMDEBUG(ID_APP,"verbose [%s]\n",(cfg->verbose?"Y":"N")); MMDEBUG(ID_APP,"host [%s]\n",cfg->host); MMDEBUG(ID_APP,"port [%d]\n",cfg->port); MMDEBUG(ID_APP,"hbeat [%d]\n",cfg->hbeat); MMDEBUG(ID_APP,"block [%s]\n",(cfg->blocking==0?"N":"Y")); MMDEBUG(ID_APP,"cycles [%d]\n",cfg->cycles); MMDEBUG(ID_APP,"bsize [%d]\n",cfg->bsize); }
void Backend::Finalize(void) { MMDEBUG("Dummy audio backend finalized"); }
bool Backend::Initialize(void) { MMDEBUG("Dummy audio backend initialized"); return(true); }
// Porting the pango-myanmar module for reordering a syllable correctly when shape it. static HB_Bool myanmar_shape_syllable(HB_Bool openType, HB_ShaperItem *item, HB_Bool invalid) { /* // MMDEBUG("\nsyllable from %d len %d, str='%s'", item->item.pos, item->item.length, // item->string->mid(item->from, item->length).toUtf8().data()); */ #ifndef NO_OPENTYPE const int availableGlyphs = item->num_glyphs; #endif const HB_UChar16 *uc = item->string + item->item.pos; int vowel_e = -1; int kinzi = -1; int medial_ra = -1; int i; int len = 0; unsigned short reordered[32]; unsigned char properties[32]; enum { AboveForm = 0x01, PreForm = 0x02, PostForm = 0x04, BelowForm = 0x08 }; memset(properties, 0, 32*sizeof(unsigned char)); /* according to the table the max length of a syllable should be around 14 chars */ assert(item->item.length < 32); #ifdef MYANMAR_DEBUG printf("original:"); for (i = 0; i < (int)item->item.length; i++) { MMDEBUG(" %d: %4x", i, uc[i]); } #endif len = 0; MymrCharClass char_class; int basE = 0, cursor = 0; while (basE < (int)item->item.length) { medial_ra = -1; /* There is no Medial Ra, if found this value will change */ kinzi = -1; /* There is no Kinzi, if found this value will change */ if (getMyanmarCharClass(uc[cursor]) & Mymr_CF_VIRAMA) basE = findBase(uc, cursor, (int)item->item.length); else basE = findBase(uc, cursor + 1, (int)item->item.length); for (i = cursor; i < basE; i += 1) { char_class = getMyanmarCharClass(uc[i]); /* look for kinzi and remember position */ if (((char_class & Mymr_CF_CLASS_MASK) == Mymr_CC_NGA) && (i + 2 < basE) && ((getMyanmarCharClass(uc[i + 1]) & Mymr_CF_CLASS_MASK) == Mymr_CC_ASAT) && (getMyanmarCharClass(uc[i + 2]) & Mymr_CF_VIRAMA)) { if (i + 3 == (int)item->item.length) { reordered[len] = Mymr_C_DOTTED_CIRCLE; len += 1; } else if (getMyanmarCharClass(uc[i + 3]) & Mymr_CF_CONSONANT) { kinzi = i; cursor += 3; } } /* if vowel e, wirte it out */ if (i > 0 && ((getMyanmarCharClass(uc[i -1]) & Mymr_CF_CLASS_MASK) != Mymr_CC_CONSONANT) && (char_class & Mymr_CF_DEP_VOWEL) && (char_class & Mymr_CF_POS_BEFORE)) { reordered[len] = Mymr_C_VOWEL_E; properties[len] = PostForm; len += 1; } /* look for medial ra and remember position */ if ((char_class & Mymr_CF_CLASS_MASK) == Mymr_CC_MEDIAL_R) { medial_ra = i; } } /* write medial ra if found */ if (medial_ra > -1) { reordered[len] = Mymr_C_MEDIAL_R; properties[len] = PreForm; len += 1; } /* shall we add a dotted circle? * If in the position in which the base should be (first char in the string) there is * a character that has the Dotted circle flag (a character that cannot be a base) * then write a dotted circle */ if (getMyanmarCharClass(uc[cursor]) & Mymr_CF_DOTTED_CIRCLE) { /* add dotted circle */ reordered[len] = Mymr_C_DOTTED_CIRCLE; len += 1; } /* copy what is left to the output, skipping before vowels and * medial Ra if they are present */ for (i = cursor; i < basE; i += 1) { char_class = getMyanmarCharClass(uc[i]); /* skip vowel e, it was already processed */ if (i > 0 && ((getMyanmarCharClass(uc[i -1]) & Mymr_CF_CLASS_MASK) != Mymr_CC_CONSONANT) &&(char_class & Mymr_CF_DEP_VOWEL) && (char_class & Mymr_CF_POS_BEFORE)) { continue; } /* skip medial ra, it was already processed */ if (i == medial_ra) { continue; } switch (char_class & Mymr_CF_POS_MASK) { case Mymr_CF_POS_ABOVE: reordered[len] = uc[i]; properties[len] = AboveForm; len += 1; break; case Mymr_CF_POS_AFTER: reordered[len] = uc[i]; properties[len] = PostForm; len += 1; break; case Mymr_CF_POS_BELOW: reordered[len] = uc[i]; properties[len] = BelowForm; len += 1; break; default: /* assign the correct flags to Medials */ if ((char_class & Mymr_CF_MEDIAL) && i + 1 < basE) { if ((char_class & Mymr_CF_CLASS_MASK) == Mymr_CC_MEDIAL_Y) { /* medial ya which possess below and right */ reordered[len] = uc[i]; properties[len] = PostForm; len += 1; break; } else { /* others wa, ha only below */ reordered[len] = uc[i]; properties[len] = BelowForm; len += 1; break; } } if ((char_class & Mymr_CF_VIRAMA) && i + 1 < basE) { if ((getMyanmarCharClass(uc[i + 1]) & Mymr_CF_CLASS_MASK) == Mymr_CC_CONSONANT) { /* subscript consonant */ reordered[len] = uc[i]; properties[len] = BelowForm; len += 1; break; } } /* assign the correct flags to consonant with subscript consonant */ if ((char_class & Mymr_CF_CONSONANT) && i + 2 < basE) { if ((getMyanmarCharClass(uc[i + 1]) & Mymr_CF_VIRAMA) && (getMyanmarCharClass(uc[i + 2]) & Mymr_CF_CLASS_MASK) == Mymr_CC_CONSONANT) { reordered[len] = uc[i]; properties[len] = BelowForm; len += 1; break; } } /* kinzi_to_be */ if (((char_class & Mymr_CF_CLASS_MASK) == Mymr_CC_NGA) && (getMyanmarCharClass(uc[i + 1]) & Mymr_CF_ASAT) && (getMyanmarCharClass(uc[i + 2]) & Mymr_CF_VIRAMA) ) { reordered[len] = uc[i]; i += 1; reordered[len + 1] = uc[i]; i += 1; reordered[len + 2] = uc[i]; properties[len] = AboveForm; properties[len + 1] = AboveForm; properties[len + 2] = AboveForm; len += 3; break; } /* default - any others */ reordered[len] = uc[i]; len += 1; break; }/* switch */ if (kinzi > -1 && i == cursor) { reordered[len] = Mymr_C_NGA; reordered[len + 1] = Mymr_C_ASAT; reordered[len + 2] = Mymr_C_VIRAMA; properties[len] = AboveForm; properties[len + 1] = AboveForm; properties[len + 2] = AboveForm; len += 3; } } /* for: loop for a baseE */ cursor = basE; } /* while: loop for a syllable*/ if (!item->font->klass->convertStringToGlyphIndices(item->font, reordered, len, item->glyphs, &item->num_glyphs, item->item.bidiLevel % 2)) return FALSE; MMDEBUG("after shaping: len=%d", len); for (i = 0; i < len; i++) { item->attributes[i].mark = FALSE; item->attributes[i].clusterStart = FALSE; item->attributes[i].justification = 0; item->attributes[i].zeroWidth = FALSE; MMDEBUG(" %d: %4x property=%x", i, reordered[i], properties[i]); } /* now we have the syllable in the right order, and can start running it through open type. */ #ifndef NO_OPENTYPE if (openType) { hb_uint32 where[32]; for (i = 0; i < len; ++i) { where[i] = ~(PreSubstProperty | BelowSubstProperty | AboveSubstProperty | PostSubstProperty | CligProperty | PositioningProperties); if (properties[i] & PreForm) where[i] &= ~PreFormProperty; if (properties[i] & BelowForm) where[i] &= ~BelowFormProperty; if (properties[i] & AboveForm) where[i] &= ~AboveFormProperty; if (properties[i] & PostForm) where[i] &= ~PostFormProperty; } HB_OpenTypeShape(item, where); if (!HB_OpenTypePosition(item, availableGlyphs, /*doLogClusters*/FALSE)) return FALSE; } else #endif { MMDEBUG("Not using openType"); HB_HeuristicPosition(item); } item->attributes[0].clusterStart = TRUE; return TRUE; }