vtutf8.c

来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 286 行

C
286
字号
/*++

Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.


Module Name:

    vtutf8.c
    
Abstract: 
    

Revision History
--*/

#include "Terminal.h"

VOID
VTUTF8RawDataToUnicode (
  IN  TERMINAL_DEV    *TerminalDevice
  )
{
  UTF8_CHAR           Utf8Char;
  UINT8               ValidBytes;
  UINT16              UnicodeChar;
  
  ValidBytes = 0;
  //
  // pop the raw data out from the raw fifo,
  // and translate it into unicode, then push 
  // the unicode into unicode fifo, until the raw fifo is empty.
  //
  while (!IsRawFiFoEmpty (TerminalDevice)) {
    
    GetOneValidUtf8Char (TerminalDevice,&Utf8Char,&ValidBytes);
    
    if (ValidBytes < 1 || ValidBytes > 3) {
      continue;
    }
      
    Utf8ToUnicode (Utf8Char,ValidBytes,&UnicodeChar); 
    
    UnicodeFiFoInsertOneKey (TerminalDevice,UnicodeChar);   
  }
}   

VOID
GetOneValidUtf8Char (
  IN  TERMINAL_DEV      *Utf8Device,
  OUT UTF8_CHAR         *Utf8Char,
  OUT UINT8             *ValidBytes
  )
{
  UINT8                 Temp;
  UINT8                 Index;
  BOOLEAN               FetchFlag;
  
  Temp      = 0;
  Index     = 0;
  FetchFlag = TRUE;
  
  //
  // if no valid Utf8 char is found in the RawFiFo,
  // then *ValidBytes will be zero.
  //
  *ValidBytes = 0;
  
  while (!IsRawFiFoEmpty (Utf8Device)) {
    
    RawFiFoRemoveOneKey (Utf8Device,&Temp);
    
    switch (*ValidBytes) {
      
      case 0:
        if ((Temp & 0x80) == 0) {     
          
          //
          // one-byte utf8 char
          //
          
          *ValidBytes = 1;
          
          Utf8Char->Utf8_1 = Temp;
          
          FetchFlag = FALSE;
        
        } else if ((Temp & 0xe0) == 0xc0) {
          
          //
          // two-byte utf8 char
          //
          
          *ValidBytes = 2;
          
          Utf8Char->Utf8_2[1] = Temp;
          
        } else if ((Temp & 0xf0) == 0xe0) {
          
          //
          // three-byte utf8 char
          //
          
          *ValidBytes = 3;
          
          Utf8Char->Utf8_3[2] = Temp;
          
          Index ++;
          
        } else {
          
          //
          // reset *ValidBytes to zero, let valid utf8 char search restart
          //
          *ValidBytes = 0 ;
        }
        
        break;
      
      case 2:
        if ((Temp & 0xc0) == 0x80) {
          
          Utf8Char->Utf8_2[0] = Temp;
          
          FetchFlag = FALSE;
        
        } else {
          
          *ValidBytes = 0;
        }
        break;
      
      case 3:
        if ((Temp & 0xc0) == 0x80) {
          
          Utf8Char->Utf8_3[2 - Index] = Temp;
          Index ++;
          if (Index == 3) {
            FetchFlag =FALSE;
          }
        } else {
          
          *ValidBytes = 0;
          Index = 0;
        }
        break;
        
      default:
        break;
    }
    
    if (!FetchFlag) {
      break;
    }  
  }
    
  return;
}   


VOID
Utf8ToUnicode (
  IN  UTF8_CHAR       Utf8Char,
  IN  UINT8           ValidBytes,
  OUT CHAR16          *UnicodeChar
  ) 
{
  UINT8               UnicodeByte0;
  UINT8               UnicodeByte1;
  UINT8               Byte0;
  UINT8               Byte1;
  UINT8               Byte2;
  
  *UnicodeChar = 0;
  
  //
  // translate utf8 code to unicode, in terminal standard,
  // up to 3 bytes utf8 code is supported.
  //
  switch (ValidBytes) {
    case 1:
      //
      // one-byte utf8 code
      //
      *UnicodeChar = (UINT16)Utf8Char.Utf8_1;
      break;
      
    case 2:
      //
      // two-byte utf8 code
      //
      Byte0 = Utf8Char.Utf8_2[0];
      Byte1 = Utf8Char.Utf8_2[1];
      
      UnicodeByte0 = (UINT8)( (Byte1 << 6) | (Byte0 & 0x3f) );
      UnicodeByte1 = (UINT8)( (Byte1 >> 2) & 0x07 ) ;
      *UnicodeChar = (UINT16)( UnicodeByte0 | (UnicodeByte1 << 8) );
      break;
      
    case 3:
      //
      // three-byte utf8 code
      //
      Byte0 = Utf8Char.Utf8_3[0];
      Byte1 = Utf8Char.Utf8_3[1];
      Byte2 = Utf8Char.Utf8_3[2];
      
      UnicodeByte0 = (UINT8)( (Byte1 << 6) | (Byte0 & 0x3f) );
      UnicodeByte1 = (UINT8)( (Byte2 << 4) | ((Byte1 >> 2) & 0x0f) );
      *UnicodeChar = (UINT16)( UnicodeByte0 | (UnicodeByte1 << 8) );
      
    default:
      break;
  }
  
  return;
}   




VOID
UnicodeToUtf8 (
  IN  CHAR16      Unicode,
  OUT UTF8_CHAR   *Utf8Char,
  OUT UINT8       *ValidBytes
  )
{
  UINT8           UnicodeByte0;
  UINT8           UnicodeByte1;
  //
  // translate unicode to utf8 code
  //
  UnicodeByte0 = (UINT8)Unicode;
  UnicodeByte1 = (UINT8)(Unicode >> 8);
  
  if (Unicode < 0x0080) {
    
    Utf8Char->Utf8_1 = (UINT8)(UnicodeByte0 & 0x7f);
    *ValidBytes = 1;
    
  } else if (Unicode < 0x0800) {
    
    //
    // byte sequence: high -> low
    //                Utf8_2[0], Utf8_2[1]
    //
    Utf8Char->Utf8_2[1] = (UINT8)((UnicodeByte0 & 0x3f) + 0x80);
    Utf8Char->Utf8_2[0] = (UINT8)((((UnicodeByte1 << 2 )+ (UnicodeByte0 >> 6)) & 0x1f ) + 0xc0);
    
    *ValidBytes = 2;
    
  } else {
    //
    // byte sequence: high -> low
    //                Utf8_3[0], Utf8_3[1], Utf8_3[2]
    //
    Utf8Char->Utf8_3[2] = (UINT8)((UnicodeByte0 & 0x3f) + 0x80);
    Utf8Char->Utf8_3[1] = (UINT8)((((UnicodeByte1 << 2) + (UnicodeByte0 >> 6)) & 0x3f) + 0x80);
    Utf8Char->Utf8_3[0] = (UINT8)(((UnicodeByte1 >> 4) & 0x0f) + 0xe0);

    *ValidBytes = 3;
  }
}   


EFI_STATUS
VTUTF8TestString (
  IN  TERMINAL_DEV    *TerminalDevice,
  IN  CHAR16          *WString
  )
{
  //
  // to utf8, all kind of characters are supported.
  //
  return EFI_SUCCESS;
}   


⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?