/** * Performs digit and letter shaping. * * @param pTransform Pointer to the <code>UBiDiTransform</code> structure. * @param pErrorCode Pointer to the error code value. * * @return Whether or not this function modifies the text. Besides the return * value, the caller should also check <code>U_SUCCESS(*pErrorCode)</code>. */ static UBool action_shapeArabic(UBiDiTransform *pTransform, UErrorCode *pErrorCode) { if ((pTransform->letters | pTransform->digits) == 0) { return FALSE; } if (pTransform->pActiveScheme->lettersDir == pTransform->pActiveScheme->digitsDir) { doShape(pTransform, pTransform->letters | pTransform->digits | pTransform->pActiveScheme->lettersDir, pErrorCode); } else { doShape(pTransform, pTransform->digits | pTransform->pActiveScheme->digitsDir, pErrorCode); if (U_SUCCESS(*pErrorCode)) { updateSrc(pTransform, pTransform->dest, *pTransform->pDestLength, *pTransform->pDestLength, pErrorCode); doShape(pTransform, pTransform->letters | pTransform->pActiveScheme->lettersDir, pErrorCode); } } return TRUE; }
QModelIndex cast( NifModel * nif, const QModelIndex & index ) { QFile file( SKEL_DAT ); if ( file.open( QIODevice::ReadOnly ) ) { QDataStream stream( &file ); TransMap local; TransMap world; QString name; do { stream >> name; if ( !name.isEmpty() ) { Transform t; stream >> t; local.insert( name, t ); stream >> t; world.insert( name, t ); } } while ( ! name.isEmpty() ); TransMap bones; doBones( nif, index, Transform(), local, bones ); foreach ( int link, nif->getChildLinks( nif->getBlockNumber( index ) ) ) { QModelIndex iChild = nif->getBlock( link ); if ( iChild.isValid() ) { if ( nif->itemName( iChild ) == "NiNode" ) { doNodes( nif, iChild, Transform(), world, bones ); } else if ( nif->inherits( iChild, "NiTriBasedGeom" ) ) { doShape( nif, iChild, Transform(), world, bones ); } } } nif->reset(); }
void KWMThemeClient::showEvent(QShowEvent *) { doShape(); widget()->repaint(false); }
void KWMThemeClient::resizeEvent( QResizeEvent* ) { doShape(); widget()->repaint(); }
/* * The Main Bidi Function, and the only function that should * be used by the outside world. * * line: a buffer of size count containing text to apply * the Bidirectional algorithm to. */ int doBidi(BLOCKTYPE line, int count, int applyShape, int reorderCombining, int * v2l, int * l2v) { unsigned char* types; unsigned char* levels; unsigned char paragraphLevel; unsigned char tempType, tempTypeSec; int i, j, imax, fX, fAL, fET, fNSM, tempInt; CHARTYPE* shapeTo; if (v2l) { for(i=0; i<count; i++) { v2l[i] = i; l2v[i] = i; } } fX = fAL = fET = fNSM = 0; for(i=0; i<count; i++) { switch(GetType(line[i])) { case AL: case R: fAL = 1; break; case LRE: case LRO: case RLE: case RLO: case PDF: case BN: fX = 1; break; case ET: fET = 1; break; case NSM: fNSM = 1; break; } } if(!fAL && !fX) return 0; /* Initialize types, levels */ types = (unsigned char*)malloc(sizeof(unsigned char) * count); levels = (unsigned char*)malloc(sizeof(unsigned char) * count); if(applyShape) shapeTo = (CHARTYPE*)malloc(sizeof(CHARTYPE) * count); /* Rule (P1) NOT IMPLEMENTED * P1. Split the text into separate paragraphs. A paragraph separator is * kept with the previous paragraph. Within each paragraph, apply all the * other rules of this algorithm. */ /* Rule (P2), (P3) * P2. In each paragraph, find the first character of type L, AL, or R. * P3. If a character is found in P2 and it is of type AL or R, then set * the paragraph embedding level to one; otherwise, set it to zero. */ paragraphLevel = GetParagraphLevel(line, count); /* Rule (X1), (X2), (X3), (X4), (X5), (X6), (X7), (X8), (X9) * X1. Begin by setting the current embedding level to the paragraph * embedding level. Set the directional override status to neutral. * X2. With each RLE, compute the least greater odd embedding level. * X3. With each LRE, compute the least greater even embedding level. * X4. With each RLO, compute the least greater odd embedding level. * X5. With each LRO, compute the least greater even embedding level. * X6. For all types besides RLE, LRE, RLO, LRO, and PDF: * a. Set the level of the current character to the current * embedding level. * b. Whenever the directional override status is not neutral, * reset the current character type to the directional * override status. * X7. With each PDF, determine the matching embedding or override code. * If there was a valid matching code, restore (pop) the last * remembered (pushed) embedding level and directional override. * X8. All explicit directional embeddings and overrides are completely * terminated at the end of each paragraph. Paragraph separators are not * included in the embedding. (Useless here) NOT IMPLEMENTED * X9. Remove all RLE, LRE, RLO, LRO, PDF, and BN codes. * Here, they're converted to BN. */ count = doTypes(line, paragraphLevel, types, levels, count, fX, v2l); GETCHAR(line, count) = 0; /* Rule (W1) * W1. Examine each non-spacing mark (NSM) in the level run, and change * the type of the NSM to the type of the previous character. If the NSM * is at the start of the level run, it will get the type of sor. */ if(fNSM) { if(types[0] == NSM) types[0] = paragraphLevel; for(i=1; i<count; i++) { if(types[i] == NSM) types[i] = types[i-1]; /* Is this a safe assumption? * I assumed the previous, IS a character. */ } } /* Rule (W2) * W2. Search backwards from each instance of a European number until the * first strong type (R, L, AL, or sor) is found. If an AL is found, * change the type of the European number to Arabic number. */ for(i=0; i<count; i++) { if(types[i] == EN) { tempType = levels[i]; j=i; while(--j >= 0 && levels[j] == tempType) { if(types[j] == AL) { types[i] = AN; break; } else if(types[j] == R || types[j] == L) { break; } } } } /* Rule (W3) * W3. Change all ALs to R. * * Optimization: on Rule Xn, we might set a flag on AL type * to prevent this loop in L R lines only... */ doALtoR(types, count); /* Rule (W4) * W4. A single European separator between two European numbers changes * to a European number. A single common separator between two numbers * of the same type changes to that type. */ for( i=0; i<(count-1); i++) { if(types[i] == ES) { if(types[i-1] == EN && types[i+1] == EN) types[i] = EN; }else if(types[i] == CS) { if(types[i-1] == EN && types[i+1] == EN) types[i] = EN; else if(types[i-1] == AN && types[i+1] == AN) types[i] = AN; } } /* Rule (W5) * W5. A sequence of European terminators adjacent to European numbers * changes to all European numbers. * * Optimization: lots here... else ifs need rearrangement */ if(fET) { for(i=0; i<count; i++) { if(types[i] == ET) { if(types[i-1] == EN) { types[i] = EN; continue; }else if(types[i+1] == EN) { types[i] = EN; continue; }else if(types[i+1] == ET) { j=i; while(j <count && types[j] == ET) { j++; } if(types[j] == EN) types[i] = EN; } } } } /* Rule (W6) * W6. Otherwise, separators and terminators change to Other Neutral: */ for(i=0; i<count; i++) { switch(types[i]) { case ES: case ET: case CS: types[i] = ON; break; } } /* Rule (W7) * W7. Search backwards from each instance of a European number until * the first strong type (R, L, or sor) is found. If an L is found, * then change the type of the European number to L. */ for(i=0; i<count; i++) { if(types[i] == EN) { tempType = levels[i]; j=i; while(--j >= 0 && levels[j] == tempType) { if(types[j] == L) { types[i] = L; break; } else if(types[j] == R || types[j] == AL) { break; } } } } /* Rule (N1) * N1. A sequence of neutrals takes the direction of the surrounding * strong text if the text on both sides has the same direction. European * and Arabic numbers are treated as though they were R. */ tempType = paragraphLevel; for(i=0; i<count; i++) { if(types[i] == ON) { if(types[i-1] == R || types[i-1] == EN || types[i-1] == AN) tempType = R; else tempType = L; j=i; while(j < count) { tempTypeSec = types[j]; if(tempTypeSec == ON) j++; else break; } if(j == count) tempTypeSec = odd(paragraphLevel) ? R : L; if(((tempTypeSec == L || tempTypeSec == LRE) && (tempType == L)) || (((tempTypeSec == R) || (tempTypeSec == EN) || (tempTypeSec == AN)) && (tempType == R))) { while(i<j) { types[i++] = tempType; } }else i = j; } } /* Rule (N2) * N2. Any remaining neutrals take the embedding direction. */ for(i=0; i<count; i++) { if(types[i] == ON) { if((levels[i] % 2) == 0) types[i] = L; else types[i] = R; } } /* Rule (I1) * I1. For all characters with an even (left-to-right) embedding * direction, those of type R go up one level and those of type AN or * EN go up two levels. */ for(i=0; i<count; i++) { if((levels[i] % 2) == 0) { if(types[i] == R) levels[i] += 1; else if((types[i] == AN) || (types[i] == EN)) levels[i] += 2; }else { if((types[i] == L) || (types[i] == EN) || (types[i] == AN)) levels[i] += 1; } } /* Rule (I2) * I2. For all characters with an odd (right-to-left) embedding direction, * those of type L, EN or AN go up one level. */ for(i=0; i<count; i++) { if((levels[i] % 2) == 1) { if(types[i] == L || types[i] == EN || types[i] == AN) levels[i] += 1; } } /* Rule (L1) * L1. On each line, reset the embedding level of the following characters * to the paragraph embedding level: * (1)segment separators, (2)paragraph separators, * (3)any sequence of whitespace characters preceding * a segment separator or paragraph separator, * (4)and any sequence of white space characters * at the end of the line. * The types of characters used here are the original types, not those * modified by the previous phase. */ j=count-1; while(j>0 && (GetType(GETCHAR(line, j)) == WS)) { j--; } if(j < (count-1)) { for(j++; j<count; j++) levels[j] = paragraphLevel; } for(i=0; i<count; i++) { tempType = GetType(GETCHAR(line, i)); if(tempType == WS) { j=i; while((++j < count) && ((tempType == WS) || (tempType == RLE)) ) { tempType = GetType(line[j]); } if(GetType(GETCHAR(line, j)) == B || GetType(GETCHAR(line, j)) == S) { for(j--; j>=i ; j--) { levels[j] = paragraphLevel; } } }else if(tempType == B || tempType == S) levels[i] = paragraphLevel; } /* Rule (L4) * L4. A character that possesses the mirrored property as specified by * Section 4.7, Mirrored, must be depicted by a mirrored glyph if the * resolved directionality of that character is R. */ /* Note: this is implemented before L2 for efficiency */ for(i=0; i<count; i++) { if((levels[i] % 2) == 1) doMirror(&GETCHAR(line, i)); } /* Rule (L3) * L3. Combining marks applied to a right-to-left base character will at * this point precede their base character. If the rendering engine * expects them to follow the base characters in the final display * process, then the ordering of the marks and the base character must * be reversed. * Combining marks are reordered to the right of each character on an * odd level. */ if(fNSM && reorderCombining) { CHARTYPE temp; int it; for(i=0; i<count; i++) { if(GetType(GETCHAR(line, i)) == NSM && odd(levels[i])) { j=i; while((++j < count) && (GetType(GETCHAR(line, j)) == NSM)); j--; i--; for(it=j; j>i; i++, j--) { temp = GETCHAR(line, i); GETCHAR(line, i) = GETCHAR(line, j); GETCHAR(line, j) = temp; if(v2l) { tempInt = v2l[i]; v2l[i] = v2l[j]; v2l[j] = tempInt; } } i=it+1; } } } /* Shaping * Shaping is Applied to each run of levels separately.... */ if(applyShape) { for(i=0; i<count; i++) { shapeTo[i] = GETCHAR(line, i); } j=i=0; while(j < count) { if(GetType(GETCHAR(line, j)) == AL) { if(j<count && j >= i ) { tempType = levels[j]; i=j; while((i++ < count) && (levels[i] == tempType)); doShape(line, shapeTo, j, i); j=i; tempType = levels[j]; } } j++; } for(i=0; i<count; i++) { GETCHAR(line, i) = shapeTo[i]; } free(shapeTo); } /* Rule (L2) * L2. From the highest level found in the text to the lowest odd level on * each line, including intermediate levels not actually present in the * text, reverse any contiguous sequence of characters that are at that * level or higher */ /* we flip the character string and leave the level array */ imax = 0; i=0; tempType = levels[0]; while(i < count) { if(levels[i] > tempType) { tempType = levels[i]; imax=i; } i++; } /* maximum level in tempType, its index in imax. */ while(tempType > 0) /* loop from highest level to the least odd, */ { /* which i assume is 1 */ flipThisRun(line, levels, tempType, count, v2l); tempType--; } free(types); free(levels); if (l2v && v2l) { for(i=0; i<count; i++) { l2v[v2l[i]] = i; } } return count; }