/**
 * 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;
}
示例#2
0
	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();
		}
示例#3
0
void KWMThemeClient::showEvent(QShowEvent *)
{
    doShape();
    widget()->repaint(false);
}
示例#4
0
void KWMThemeClient::resizeEvent( QResizeEvent* )
{
    doShape();
    widget()->repaint();
}
示例#5
0
/*
 * 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;
}