/*
 * Draw_Buffer_ASCII_Expand_48x48.c
 *
 *  Created on: 2025/02/24
 *      Author: egaono-electronics
 */

#include "Draw_Buffer_ASCII_Expand_48x48.h"

#include "ILI9341_SPI_Draw.h"



//----------------------------------------------------------
// 描画Bufferに Font 48 x 48 の文字をセット
//----------------------------------------------------------
// 16 x 16 fontテーブルのデータを使用して
// 縦と横をそれぞれ3倍に引き伸ばして
//                          48 x 48 fontの文字を作成する。
//----------------------------------------------------------
// 引数;
// int16_t int16_Type :
//      0 : 通常表示
//      1 : 反転表示

// uint8_t *puint8_Address_font : フォント配列のポインタ

// uint16_t uint16_Length : 文字数
// uint16_t *puint16_aCode :
//                  文字コードが格納されたBufferのポインタ
// uint8_t *puint8_aBuffer : 描画Bufferのポインタ


// 戻り値:
//  なし
//----------------------------------------------------------
void Draw_Buffer_ASCII_Expand_48x48(int16_t int16_Type,
                                    uint8_t *puint8_Address_font,
                                    uint16_t uint16_Length,
                                    uint16_t *puint16_aCode,
                                    uint8_t *puint8_aBuffer)
{
  uint32_t uint32_AddressFont;

  uint32_t uint32_Position;

  uint32_t uint32_I;
  uint32_t uint32_J;
  uint32_t uint32_K;

  uint8_t uint8_Font;
  uint8_t uint8_Bit;

  uint32_t uint32_Font;
  uint32_t uint32_Bit;


  // 指定文字数分の処理を行う。
  for(uint32_I = 0;
        uint32_I < (uint32_t)uint16_Length; uint32_I++){
    // 処理する文字コードの
    //          フォント配列の位置を算出してセットする。
    uint32_AddressFont
                = (uint32_t)puint16_aCode[uint32_I] * 32;

    // フォントデータをBufferにセットする。
    for(uint32_J = 0;
        uint32_J < (uint16_t)def_DotLengthwise_Font16x16;
        uint32_J++){
      // フォントデータをセットするバッファの位置を計算
      uint32_Position
            = (uint32_t)uint16_Length * 18 * (uint16_t)uint32_J
            + uint32_I * 6;

      //----------------------------------------------------
      // 前半 8bits
      //----------------------------------------------------
      // フォント配列 ASCII 16x16 から
      //    指定文字コードのフォントデータを抜き出す。
      uint8_Font = puint8_Address_font[
                        uint32_AddressFont + uint32_J * 2];

      //------------------------------------------------
      // フォントデータを3倍に引き伸ばす。
      //------------------------------------------------
      uint8_Bit = 0x80;
      uint32_Font = 0;
      uint32_Bit = 0x800000;
      for(uint32_K = 0; uint32_K < 8; uint32_K++){
        if((uint8_Font & uint8_Bit) == 0){
          uint32_Font &= (uint32_Bit ^ 0xFFFFFF);
          uint32_Bit >>= 1;
          uint32_Font &= (uint32_Bit ^ 0xFFFFFF);
          uint32_Bit >>= 1;
          uint32_Font &= (uint32_Bit ^ 0xFFFFFF);
          uint32_Bit >>= 1;
        }
        else{
          uint32_Font |= uint32_Bit;
          uint32_Bit >>= 1;
          uint32_Font |= uint32_Bit;
          uint32_Bit >>= 1;
          uint32_Font |= uint32_Bit;
          uint32_Bit >>= 1;
        }

        uint8_Bit >>= 1;
      }
      //------------------------------------------------

      // バッファにフォントデータをセットする。
      if(int16_Type == 0){
        // 通常表示

        // 1行目をセット
        puint8_aBuffer[uint32_Position]
            = (uint8_t)((uint32_Font & 0xFF0000) >> 16);
        puint8_aBuffer[uint32_Position + 1]
            = (uint8_t)((uint32_Font & 0x00FF00) >> 8);
        puint8_aBuffer[uint32_Position + 2]
            = (uint8_t)(uint32_Font & 0x0000FF);

        // 2行目をセット
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 6]
            = (uint8_t)((uint32_Font & 0xFF0000) >> 16);
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 6 + 1]
            = (uint8_t)((uint32_Font & 0x00FF00) >> 8);
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 6 + 2]
            = (uint8_t)(uint32_Font & 0x0000FF);

        // 3行目をセット
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 12]
            = (uint8_t)((uint32_Font & 0xFF0000) >> 16);
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 12 + 1]
            = (uint8_t)((uint32_Font & 0x00FF00) >> 8);
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 12 + 2]
            = (uint8_t)(uint32_Font & 0x0000FF);
      }
      else{
        // 反転表示

        // 1行目をセット
        puint8_aBuffer[uint32_Position]
            = (uint8_t)((uint32_Font & 0xFF0000) >> 16) ^ 0xFF;
        puint8_aBuffer[uint32_Position + 1]
            = (uint8_t)((uint32_Font & 0x00FF00) >> 8) ^ 0xFF;
        puint8_aBuffer[uint32_Position + 2]
            = (uint8_t)(uint32_Font & 0x0000FF) ^ 0xFF;

        // 2行目をセット
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 6]
            = (uint8_t)((uint32_Font & 0xFF0000) >> 16) ^ 0xFF;
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 6 + 1]
            = (uint8_t)((uint32_Font & 0x00FF00) >> 8) ^ 0xFF;
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 6 + 2]
            = (uint8_t)(uint32_Font & 0x0000FF) ^ 0xFF;

        // 3行目をセット
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 12]
            = (uint8_t)((uint32_Font & 0xFF0000) >> 16) ^ 0xFF;
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 12 + 1]
            = (uint8_t)((uint32_Font & 0x00FF00) >> 8) ^ 0xFF;
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 12 + 2]
            = (uint8_t)(uint32_Font & 0x0000FF) ^ 0xFF;
      }


      //----------------------------------------------------
      // 後半 8bits
      //----------------------------------------------------
      // フォント配列 ASCII 16x16 から
      //    指定文字コードのフォントデータを抜き出す。
      uint8_Font = puint8_Address_font[
                    uint32_AddressFont + uint32_J * 2 + 1];

      //------------------------------------------------
      // フォントデータを3倍に引き伸ばす。
      //------------------------------------------------
      uint8_Bit = 0x80;
      uint32_Font = 0;
      uint32_Bit = 0x800000;
      for(uint32_K = 0; uint32_K < 8; uint32_K++){
        if((uint8_Font & uint8_Bit) == 0){
          uint32_Font &= (uint32_Bit ^ 0xFFFFFF);
          uint32_Bit >>= 1;
          uint32_Font &= (uint32_Bit ^ 0xFFFFFF);
          uint32_Bit >>= 1;
          uint32_Font &= (uint32_Bit ^ 0xFFFFFF);
          uint32_Bit >>= 1;
        }
        else{
          uint32_Font |= uint32_Bit;
          uint32_Bit >>= 1;
          uint32_Font |= uint32_Bit;
          uint32_Bit >>= 1;
          uint32_Font |= uint32_Bit;
          uint32_Bit >>= 1;
        }

        uint8_Bit >>= 1;
      }
      //------------------------------------------------

      // バッファにフォントデータをセットする。
      if(int16_Type == 0){
        // 通常表示

        // 1行目をセット
        puint8_aBuffer[uint32_Position + 3]
            = (uint8_t)((uint32_Font & 0xFF0000) >> 16);
        puint8_aBuffer[uint32_Position + 4]
            = (uint8_t)((uint32_Font & 0x00FF00) >> 8);
        puint8_aBuffer[uint32_Position + 5]
            = (uint8_t)(uint32_Font & 0x0000FF);

        // 2行目をセット
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 6 + 3]
            = (uint8_t)((uint32_Font & 0xFF0000) >> 16);
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 6 + 4]
            = (uint8_t)((uint32_Font & 0x00FF00) >> 8);
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 6 + 5]
            = (uint8_t)(uint32_Font & 0x0000FF);

        // 3行目をセット
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 12 + 3]
            = (uint8_t)((uint32_Font & 0xFF0000) >> 16);
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 12 + 4]
            = (uint8_t)((uint32_Font & 0x00FF00) >> 8);
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 12 + 5]
            = (uint8_t)(uint32_Font & 0x0000FF);
      }
      else{
        // 反転表示

        // 1行目をセット
        puint8_aBuffer[uint32_Position + 3]
            = (uint8_t)((uint32_Font & 0xFF0000) >> 16) ^ 0xFF;
        puint8_aBuffer[uint32_Position + 4]
            = (uint8_t)((uint32_Font & 0x00FF00) >> 8) ^ 0xFF;
        puint8_aBuffer[uint32_Position + 5]
            = (uint8_t)(uint32_Font & 0x0000FF) ^ 0xFF;

        // 2行目をセット
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 6 + 3]
            = (uint8_t)((uint32_Font & 0xFF0000) >> 16) ^ 0xFF;
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 6 + 4]
            = (uint8_t)((uint32_Font & 0x00FF00) >> 8) ^ 0xFF;
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 6 + 5]
            = (uint8_t)(uint32_Font & 0x0000FF) ^ 0xFF;

        // 3行目をセット
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 12 + 3]
            = (uint8_t)((uint32_Font & 0xFF0000) >> 16) ^ 0xFF;
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 12 + 4]
            = (uint8_t)((uint32_Font & 0x00FF00) >> 8) ^ 0xFF;
        puint8_aBuffer[uint32_Position
                        + (uint32_t)uint16_Length * 12 + 5]
            = (uint8_t)(uint32_Font & 0x0000FF) ^ 0xFF;
      }
    }
  }
}
