ぬの部屋(仮)
nu-no-he-ya
  • 1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
         12
    3456789
    10111213141516
    17181920212223
    2425262728  
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
       1234
    567891011
    12131415161718
    19202122232425
    26272829   
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728     
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28      
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
    1234567
    891011121314
    15161718192021
    22232425262728
           
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
         12
    3456789
    10111213141516
    17181920212223
    242526272829 
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
        123
    45678910
    11121314151617
    18192021222324
    25262728   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    15161718192021
    293031    
           
         12
    3456789
    10111213141516
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728     
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
          1
    2345678
    9101112131415
    16171819202122
    232425262728 
           
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
  • Local by flywheel + All-in-One WP Migration + FTP clientでWordPressサイトのコピーをローカルに作る話

    概要

    ・Local by flywheelで環境を作るときに、 PreferではなくCustomで作る。こうしないとphp.iniの設定などが難しい

    ・Local by flywheelで環境を作るときに、元のサイトとPHPのバージョンを合わせておく必要がある。少なくともPHP5系列とPHP7系列には互換性がないらしいのでここが違うと動かない

    ・Local by flywheelで作られた環境ではファイルアップロード容量がphp.iniの初期設定により小さくなっているので、php.ini.hbsのupload_max_filesize等々を編集し、All-in-One WP Migrationでエクスポートした.wpressファイルをインポートできるサイズに拡張しておく必要がある

    ・ Local by flywheel側で、All-in-One WP Migrationはデフォルトでは2021/11の時点で300Mしかインポートできないので、プラグインを編集して制約を撤廃する。

    ・元サイト側で、 All-in-One WP Migration でエクスポートをする際に、ドメイン名をローカルのドメイン名に文字列置換しておく

    ・元サイト側のサイズが極めて大きい場合、ローカル側のAll-in-One WP Migrationのインポート処理が終わらなくなってしまうので、メディアファイルを省いてエクスポートする。(私の場合全体で1GB近くあり、上記設定を行ってもインポート処理が進まなくなってしまったので、メディアファイル抜きで約300Mまで落とした)

    ・ローカル側にAll-in-One WP Migrationをインストールし、インポートする。結構時間がかかる

    ・元サイトにFTP接続し、wp-content/uploads/ ディレクトリを別途ダウンロードし、Local by flywheel側のwordpressのディレクトリに上書きする

    Local by Flywheelで環境構築

    ローカル環境を作るときはCustomで。あとPHPのバージョンを合わせる。

    php.ini.hbs でアップロード上限をwpressファイル以上にあげておく。ただしwpressファイルが大きすぎるとそれでも無理かもしれない。

    Local by Flywheel側のファイルアップロード上限撤廃

    私は一応全部を2048Mに設定している

     

    memory_limit = 2048M

    post_max_size = 2048M

    upload_max_filesize = 2048M

     

    Local by Flywheel側のAll-in-One WP Migrationのファイルインポート上限撤廃

    ローカル側のWordpressにログインし、All-in-One WP Migration をインストール。同プラグインのインポート上限を上げるためにプラグインエディタでAll-in-One WP Migrationを編集する

    408行目あたりにある「Max File Size」の項目を 536870912*10 に変更

    // =================
    // = Max File Size =
    // =================
    define( 'AI1WM_MAX_FILE_SIZE', 536870912*10 );

    元サイトのデータをエクスポート

    元サイト側のAll-in-One WP Migrationで、エクスポート時、ドメインの置換を設定し、大きくなることが懸念される場合はメディアファイルをエクスポートしない設定をする。

    Local by Flywheel側のwordpressにてインポート

    ローカル側で普通にインポート→待つ。

    ファイルが大きすぎる場合、あるいはローカルと元サイトでPHPバージョンが違う場合、100%から動かない。

    なおファイルのサイズは360MBまで減らしても数分は待ったので安易に見切りをつけてはいけない。HDDかSSDかなど環境に持っても違うと思う。

    メディアファイルを別途FTPでダウンロード・上書

    最後にwp-content/uploads/ をサーバーからコピーして上書。完成。

    icu::UnicodeStringで正規表現 icu::RegexMatcher

    icu::RegexMatcher

    #include <fstream>
    #include <iostream>
    #include <vector>
    
    #include <unicode/ucnv.h>
    #include <unicode/regex.h>
    
    
    // 要リンク
    #pragma comment(lib, "icuuc.lib")
    
    //regex.hに必要
    #pragma comment(lib, "icuin.lib")
    
    
    // 以下のdllを要求される
    // icudt69.dll
    // icuuc69.dll
    
    // icuin69.dll regexに必要
    
    
    int main()
    {
      std::fstream w(
        "C:\\dev\\icu-test\\converted.txt",
        std::ios::out | std::ios::binary | std::ios::trunc);
    
    
      std::u16string u16s = u"aい山うkえ👨‍👧經お经";
    
      icu::UnicodeString ustr(u16s.c_str());
    
      UErrorCode status = U_ZERO_ERROR;
      icu::RegexMatcher matcher(u"[う-お].+[あ-お]", 0, status);
    
      matcher.reset(ustr);
    
    if (matcher.find()) { icu::UnicodeString ret; int start = matcher.start(status); // string index of start of match. int end = matcher.end(status); ustr.extract( start, end - start, ret ); w.write((char*)ret.getBuffer(), ret.length()*2); } ///////////////////////////////// }

    いくつかの例

    ICUライブラリで一文字replace

    // char16のindexとその文字を構成するchar16の個数のリスト作成
    std::vector<std::pair<int32_t, int32_t>> getIndexList(const icu::UnicodeString& s) {
    
      std::vector<std::pair<int32_t, int32_t>> c_c;
    
      UErrorCode err;
      icu::BreakIterator* bi = icu::BreakIterator::createCharacterInstance(
        icu::Locale::getDefault(), err);
      bi->setText(s);
    
      int32_t current = bi->first();
      while (current != icu::BreakIterator::DONE) {
    
        int32_t prev = current;
        current = bi->next();
    
        if (current == UBRK_DONE) break;
    
        c_c.emplace_back(prev, current - prev );
    
      }
    
      return c_c;
    }
    void WinPaint(HWND hWnd) {
    
      // 元の文字列の定義
      std::u16string u16s = u"aあغ山👨‍👧經经";
    
      ////////////////////////////////////////
      ////////////////////////////////////////
    
      icu::UnicodeString usr(u16s.c_str());
    
      // char16のindexとその文字を構成するchar16の個数のリスト作成
      std::vector<std::pair<int32_t, int32_t>> ilis = getIndexList(usr);
    
      // 文字の置き換え
      icu::UnicodeString B("B");
      // 4文字目を「B」に書き換える
      // UnicodeString::replace(先頭index,置換前の要素数,置換後の文字)
      usr.replace(ilis[4].first, ilis[4].second, B);
    
    
      ////////////////////////////////////////
      ////////////////////////////////////////
    
    
      ////////////////////////////
      //フォトの設定
      HDC hdc;
      PAINTSTRUCT ps;
      hdc = BeginPaint(hWnd, &ps);
      SetTextColor(hdc, RGB(0, 0, 0));  //文字の色を設定
      SetBkColor(hdc, RGB(230, 230, 230));  //文字の背景色を設定
      HFONT backup = (HFONT)SelectObject(hdc, hFont1);  //Step2  フォントを適応
      TEXTMETRIC tm;
      GetTextMetrics(hdc, &tm);
      int TH = 10;
    
      ////////////////////////////
      //文字を一文字(書記素)ずつ表示
    
      UErrorCode err;
      icu::BreakIterator* bi = icu::BreakIterator::createCharacterInstance(
        icu::Locale::getDefault(), err);
      bi->setText(usr);
    
      int32_t current = bi->first();
      while (current != icu::BreakIterator::DONE) {
    
        int32_t prev = current;
        current = bi->next();
    
        if (current == UBRK_DONE) break;
    
        int32_t count = current - prev;//文字の長さ
    
        icu::UnicodeString e;
        usr.extract(prev, count, e);
        // win32api のWCHARはutf16なのでただキャストするだけで変換できる
        TextOutW(hdc, 10, TH, (WCHAR*)e.getBuffer(), e.length());//文字を書く
    
        //改行
        TH += tm.tmHeight+5;
      }
    
    
    
      SelectObject(hdc, backup);
    
      EndPaint(hWnd, &ps);
    }
    

    ICUライブラリBreakIteratorでutf16を一文字ずつ表示する方法いくつか

    void WinPaint(HWND hWnd) {
    
      // 元の文字列の定義
      std::u16string u16s = u"aあغ山👨‍👧經经";
    
      /////////////////////////////
      // ICUの設定
    
      icu::UnicodeString usr(u16s.c_str());
    
      UErrorCode err;
      icu::BreakIterator* bi = icu::BreakIterator::createCharacterInstance(
        icu::Locale::getDefault(),err);
      bi->setText(usr);
    
      ////////////////////////////
      //フォトの設定
      HDC hdc;
      PAINTSTRUCT ps;
      hdc = BeginPaint(hWnd, &ps);
      SetTextColor(hdc, RGB(0, 0, 0));  //文字の色を設定
      SetBkColor(hdc, RGB(230, 230, 230));  //文字の背景色を設定
      HFONT backup = (HFONT)SelectObject(hdc, hFont1);  //Step2  フォントを適応
      TEXTMETRIC tm;
      GetTextMetrics(hdc, &tm);
      int TH = 10;
      ////////////////////////////
      //文字を一文字(書記素)ずつ表示
    
    
      int32_t current = bi->first();
      while (current != icu::BreakIterator::DONE) {
    
        // 文字の長さを知る必要があるので、
        // 「現在の文字の位置」と「前の文字の位置」が必要
        int32_t prev = current;
        current = bi->next();
    
        if (current == UBRK_DONE) {
          break;
        }
    
        int32_t count = current - prev;//文字の長さ
    
    
        TextOutW(hdc, 10, TH, (WCHAR*)& usr.getBuffer()[prev], count);//文字を書く
    
        //改行
        TH += tm.tmHeight+5;
      }
    
      SelectObject(hdc, backup);
    
      EndPaint(hWnd, &ps);
    }
    

    一文字表示する部分の記述方法

        TextOutW(hdc, 10, TH, (WCHAR*)& usr.getBuffer()[prev], count);//文字を書く
    
        icu::UnicodeString e;
        usr.extract(prev, count, e);
        // win32api のWCHARはutf16なのでただキャストするだけで変換できる
        TextOutW(hdc, 10, TH, (WCHAR*)e.getBuffer(), e.length());//文字を書く
    
        // substr(現在位置,切り取る長さ)
        std::u16string sub = u16s.substr(prev, count);
        TextOutW(hdc, 10, TH, (WCHAR*)sub.data(), count);//文字を書く
    

    なおなぜかWordpressのせいでサロゲートペアが入力できないのでサンプルから抜いている。

    prev,currentの変化

    first(),next()で操作するのはchar16_tとしての配列の要素番号。なので+1移動で2Byte移動だが、サロゲートペアや結合文字があった場合はその限りではない。

    ICUライブラリ+win32apiでutf16を一文字ずつ表示

    ICUライブラリで文字を一文字ずつ切り出したい。しかし切り出した結果をコンソール出力するのはもろもろの事情で難しく、ファイル出力は確認がめんどくさいのでウィンドウに描画する。

    #include <windows.h>
    
    #include <unicode/ucnv.h>
    #include <unicode/brkiter.h>
    
    // 要リンク
    #pragma comment(lib, "icuuc.lib")
    
    // 以下のdllを要求される
    // icudt69.dll
    // icuuc69.dll
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    WCHAR szClassName[] = L"MY_ICU_TEST";  //ウィンドウクラス
    
    LPCWSTR fontname = L"MS P ゴシック";
    
    HFONT hFont1;
    
    void WinPaint(HWND hWnd) {
    
      // 元の文字列の定義
      std::u16string u16s = u"aあغ山👨‍👧經经";
    
      /////////////////////////////
      // ICUの設定
    
      icu::UnicodeString usr(u16s.c_str());
    
      UErrorCode err;
      icu::BreakIterator* bi = icu::BreakIterator::createCharacterInstance(
        icu::Locale::getDefault(),err);
      bi->setText(usr);
    
      ////////////////////////////
      //フォトの設定
      HDC hdc;
      PAINTSTRUCT ps;
      hdc = BeginPaint(hWnd, &ps);
      SetTextColor(hdc, RGB(0, 0, 0));  //文字の色を設定
      SetBkColor(hdc, RGB(230, 230, 230));  //文字の背景色を設定
      HFONT backup = (HFONT)SelectObject(hdc, hFont1);  //フォントを適応
      TEXTMETRIC tm;
      GetTextMetrics(hdc, &tm);
      int TH = 10;
    
    //////////////////////////// //文字を一文字(書記素)ずつ表示
    int32_t current = bi->first(); while (current != icu::BreakIterator::DONE) { // 文字の長さを知る必要があるので、 // 「現在の文字の位置」と「前の文字の位置」が必要 int32_t prev = current; current = bi->next(); if (current == UBRK_DONE) { break; } int32_t count = current - prev;//文字の長さ //win32api のWCHARはutf16なのでただキャストするだけで変換できる TextOutW(hdc, 10, TH, (WCHAR*)(&u16s.data()[prev]), count);//文字を書く // こっちでもいい substr(現在位置,切り取る長さ) // std::u16string sub = u16s.substr(prev, count); // TextOutW(hdc, 10, TH, (WCHAR*)sub.data(), count);//文字を書く //改行 TH += tm.tmHeight+5; } SelectObject(hdc, backup); EndPaint(hWnd, &ps); }
    ////////////////////////////////////
    ////////////////////////////////////
    // 表示用
    ////////////////////////////////////
    ////////////////////////////////////
    
    
    int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) {
      MSG msg;
      BOOL bRet;
      WNDCLASSEX wc;
      HWND hWnd;
      ATOM atom;
    
      wc.cbSize = sizeof(WNDCLASSEX);
      wc.style = CS_HREDRAW | CS_VREDRAW;
      wc.lpfnWndProc = WndProc;
      wc.cbClsExtra = 0;
      wc.cbWndExtra = 0;
      wc.hInstance = hCurInst;
      wc.hIcon = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
      wc.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
      wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
      wc.lpszMenuName = NULL;
      wc.lpszClassName = (LPCWSTR)szClassName;
      wc.hIconSm = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
    
      if ((atom = RegisterClassEx(&wc)) == 0)return FALSE;
    
      hWnd = CreateWindow(
        MAKEINTATOM(atom), 
        L"icu test", 
        WS_OVERLAPPEDWINDOW, 
        CW_USEDEFAULT, CW_USEDEFAULT, 
        200, 500, // ウィンドウのサイズ
        NULL, NULL, hCurInst, NULL);
    
      if (!hWnd)return FALSE;
    
      ShowWindow(hWnd, nCmdShow);
      UpdateWindow(hWnd);
      while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) {
        if (bRet == -1) {
          break;
        }
        else {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
        }
      }
      return (int)msg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
      switch (msg) {
      case WM_CREATE:
        //Step1  フォント作成
        hFont1 = CreateFont(
          50, 0, //高さ, 幅
          0, 0, FW_BOLD,
          FALSE, FALSE, FALSE,
          SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS,
          CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
          VARIABLE_PITCH | FF_ROMAN, fontname);
        break;
      case WM_PAINT:
        WinPaint(hWnd);
        break;
      case WM_DESTROY:
        DeleteObject(hFont1);   //Step4. HFONTオブジェクトを破棄
        PostQuitMessage(0);
        break;
      default:
        return (DefWindowProc(hWnd, msg, wp, lp));
      }
      return 0;
    }
    

    ICUライブラリのicu::UnicodeString::extractに指定するコードページにはどんなものがあるか

    ICUライブラリを使って文字コードの変換を行うとき、例えば日本固有の文字コードに変換したいなら「Shift_JIS」や「EUC-JP」、中国固有の文字コードなら「GBK」「EUC-CN」など、変換先の文字コードを指定しなければならない。この文字コード名を「コードページ」というらしいが、Shift_JISやEUC-JPの他にどんな物があるか。

    void test() {
    
      icu::UnicodeString us(u"いろはにほへと");
    
      const char* code_page = "Shift_JIS"; // コードページ。他にどんな物があるか。
    
      char dst_data[100];
      int32_t len = us.extract(0, us.length(), dst_data, code_page);
    
      printf("%s (%d) \n",dst_data,len);
    
    }
    

    コンバータ名一覧を取得する関数

    マニュアルを読むと、どうやらConverter Namesという呼称でコードページを与えるらしい。そして使える名前一覧を取得する関数がいくつか用意されているらしい。

    https://unicode-org.github.io/icu/userguide/conversion/converters.html#converter-names

    ucnv_openAllNames

    例えば、ucnv_openAllNames は

    Get a list of all known converter names.

    と、「全ての知られているコンバータ名を取得する」と書かれている。使い方はこんな感じ。

      auto name_enum = ucnv_openAllNames(&err);
    
      int32_t len;
      const char* name;
    
      while (name = uenum_next(name_enum, &len, &err)) {
        printf("%s\n", name);
      }
      uenum_close(name_enum);
    

    ucnv_openAllNamesでイテレータを取得して、uenum_nextでイテレータを前に進めるような使い方をする。

    ただこれで得られる内容は膨大すぎてよくわからない。

    ucnv_countAvailable

    次に、ucnv_countAvailable は

    Get a list of available converter names that can be opened.

    と、「使えるコンバータのリストを取得する」と書かれている。使い方はこんな感じ。

      int32_t convcount = ucnv_countAvailable();
      for (int32_t i = 0; i < convcount; i++) {
        printf("[%03d] %s\n",i, ucnv_getAvailableName(i));
      }
    

    これでも200個以上出てくる上に、Shift_JISなどわかりやすい物がない。

    ucnv_getAliases コードページの別名一覧を取得

    そもそも同じコードページにも複数の表記法があるらしい。例えばShift_JIS,CP932,Windows-31J,MS932は(ほぼ)同じ意味になる。 ucnv_getAliases はそんな、あるコードページの仲間のコードページを探す。

    int main()
    {
      UErrorCode err;
    
      const char* ALIAS = "Shift_JIS";   // 日本語のコードページ
    
    
      // ALIAS で表されるコードページの別名一覧を表示
      uint16_t acount = ucnv_countAliases(ALIAS, &err);
      for (auto i = 0; i < acount; i++) {
        const char* code_page_arias = ucnv_getAlias(ALIAS, i, &err);
    
        printf("-- %s\n", code_page_arias);
    
      }
      
      getchar();
    }
    

    出力:

    -- ibm-943_P15A-2003
    -- ibm-943
    -- Shift_JIS
    -- MS_Kanji
    -- csShiftJIS
    -- windows-31j
    -- csWindows31J
    -- x-sjis
    -- x-ms-cp932
    -- cp932
    -- windows-932
    -- cp943c
    -- IBM-943C
    -- ms932
    -- pck
    -- sjis
    -- ibm-943_VSUB_VPUA
    -- x-MS932_0213
    -- x-JISAutoDetect

    CP932 vs Shift_JIS

    Shift_JIS を ucnv_getAliases にかけるとエイリアスが大量に出てくるのだが違いがあるのかよくわからない。拡張文字の有無など微細な違いがあるらしいCP932とShift_JISにそれぞれ変換してみた。

    #include <fstream>
    #include <iostream>
    
    #include <unicode/ucnv.h>
    #include <unicode/unistr.h>
    #pragma comment(lib, "icuuc.lib")
    
    // 以下のdllを要求される
    // icudt69.dll
    // icuuc69.dll
    
    
    void Converter(const icu::UnicodeString& us,const char* dstCode) {
    
    
      //内部形式の文字コードを目的の文字コードへ変換
      char dst_data[100];
      int32_t len = us.extract(0, us.length(), dst_data, dstCode);
    
      printf("length: %d\n", len);
    
      std::string textname = "C:\\dev\\icu-test\\converted-";
      textname += dstCode;
      textname += ".txt";
      ///////////////////////////////
    // 文字コード変換した内容をファイル出力 std::fstream w( textname, std::ios::out | std::ios::binary | std::ios::trunc); w << dst_data; }
    int main()
    {
      UErrorCode err;
    
      const char* ALIAS = "Shift_JIS";   // 日本語のコードページ
    
      //std::u16string src_data = u"いろはにほへと";       // 日本語
    
      // NEC拡張文字
      // ①②㌍
      // IBM拡張文字
      // 髙ⅱⅲ㈱
      std::u16string jps = u"①②㌍髙ⅱⅲ㈱";
    
      // ICUの内部表現へ変更
      icu::UnicodeString ustr(jps.c_str());
    
      Converter(ustr, "Shift_JIS");// コードページを指定して変換
      Converter(ustr, "CP932");
    
    
      
      getchar();
    }
    

    実行結果。特に変換できない文字は出てこなかった。

    指定できそうなコードページを調べる

    https://www.ibm.com/docs/ja/integration-bus/10.0?topic=ssmkhh-10-0-0-com-ibm-etools-mft-doc-ac00408--htm

    ICUライブラリのページではないようだがIBMのページなので、ここの一覧から選ぶことができそうである。いくつか拾い上げて ucnv_getAliases に与えると表のとおりの結果が返ってきている。

    おまけ

    中国語やギリシャ語への変換例。確認方法が面倒。Converterは前述のものを使用。

    ギリシャ語はWordでフォントをTimes New Romanにすると確認できる。

    int main()
    {
      UErrorCode err;
    
      const char* ALIAS = "EUC-CN";      // 中国語のコードページ
      std::u16string src_data = u"什么";  // 中国語
    
      icu::UnicodeString ustr(src_data.c_str());
    
      Converter(ustr, ALIAS);
      
      getchar();
    }
    
    int main()
    {
      UErrorCode err;
    
      const char* ALIAS = "ibm737";     // ギリシャ語のコードページ
      std::u16string src_data = u"πανσέληνος"; // ギリシャ語
    
      icu::UnicodeString ustr(src_data.c_str());
    
      Converter(ustr, ALIAS);
    
      getchar();
    }
    

    参考:

     

     

    本当は怖くないCP932
    https://qiita.com/kasei-san/items/cfb993786153231e5413

    ICUライブラリ(再)

    以前やったのが2014年とかだったので更新する。

    古い記事:

    1.ダウンロード

    https://icu.unicode.org/download

    公式サイトからICU4C系をクリックする。

    ICU4CはC++。

    ICU4JはJava。

    その先のページの一番下のDownloadにある、Source and binary downloads are available on the git/GitHub tag pageのリンクへ飛ぶ。

    一覧の中から、対応開発環境のものを選ぶ

    2.サンプルコード

    リンクにicuuc.libが必要。また実行時にicudt69.dll , icuuc69.dllが必要。

    #include <fstream>
    
    
    #include <unicode/ucnv.h>
    
    // icu::UnicodeString に必要
    #include <unicode/unistr.h>
    
    // 要リンク
    #pragma comment(lib, "icuuc.lib")
    
    // 以下のdllを要求される
    // icudt69.dll
    // icuuc69.dll
    
    void Converter() {
    
      std::fstream r("C:\\dev\\icu-test\\shiftjis.txt");
      std::string src_data;
      r >> src_data;
      //エラーを受け取る変数
      UErrorCode err = U_ZERO_ERROR;
    
      //入力・出力の各文字コード
      char srcCode[] = "shift-jis";
      char dstCode[] = "euc-jp";
    
      //UnicodeStringに渡す文字列の文字コードを指定する
      UConverter* srccnv = ucnv_open(srcCode, &err);
    
      //入力された文字の文字コードを内部形式に変換
      icu::UnicodeString srcstr(src_data.c_str(), src_data.length(), srccnv, err);
    
      //内部形式の文字コードを目的の文字コードへ変換
      char* dst_data = new char[100];
      srcstr.extract(0, srcstr.length(), dst_data, dstCode);
      using namespace std;
      std::fstream w("C:\\dev\\icu-test\\euc-jp.txt", ios::out | ios::binary | ios::trunc);
      w << dst_data;
    }
    
    int main()
    {
      Converter();
    }
    

    Gimp Script-fuですべてのレイヤーをマージした画像をpngにエクスポート

    file-png-save-defaults関数を使うのだが、画像番号と一緒にdrawableを指定しなければならず、したがってそのdrawableのレイヤーしか保存できない。

    全てのレイヤーをマージするにはgimp-image-merge-visible-layers関数を使えばいいが、エクスポートしたいだけでマージするわけにいかないので、gimp-image-duplicateで現在の画像をコピーし、それに対してマージを行い、保存した後でgimp-image-deleteで削除する

    ; 画像をPNG保存する自作関数。
    ; Image 画像番号
    ; Drawable レイヤー番号
    ; outpath 保存先(ファイル名を含まない)
    ; filename ファイル名(.pngを含まない)
    (define (my-save-to-png Image Drawable outpath filename)
      ; 保存処理
      (file-png-save-defaults
        RUN-NONINTERACTIVE
        Image
        Drawable
        (string-append outpath filename ".png")
        (string-append filename ".png") 
      )
    )
    
          
    ; 全てのレイヤーを統合してpngにエクスポート
    ; Image 画像番号 (gimp-image-list) で取得可能
    ; outpath 出力先のパス。C:\\test\\
    (define (my-save-png-as-single-image Image outpath )
      (begin
      
        ; 現在の画像をコピーする
        (define dummydup   '())
        (set! dummydup   (car (gimp-image-duplicate Image ) ) )
        
        ; コピーした画像の全レイヤーをマージして一つの画像にする
        (gimp-image-merge-visible-layers dummydup CLIP-TO-IMAGE )
        
        ; 保存に必要な、dummydupのdrawableを取得する
        (define activedrawable   '())
        (set! activedrawable (car (gimp-image-get-active-drawable dummydup ) ) )
        
        (my-save-to-png
          dummydup
          activedrawable
          outpath
          (car (gimp-image-get-name Image) ); 画像の名前を取得してファイル名に指定
        )
        
        (gimp-image-delete dummydup)
        
      )
    )
    ;; usage :
    ;; (gimp-image-list)
    ;; > (1 #(5))
    ;; (my-save-png-as-single-image 5 "C:\\test\\")
    ;; > (#t)
    

    Gimp側

    出力

    BlenderでPythonから画像を読み込み、アスペクト比を調整する

    Import Images as Planeを使えばする必要すらないが、Pythonコードからplaneにテクスチャを設定する場合。

    import bpy
    
    # @brief Planeオブジェクトのサイズをテクスチャ画像に合わせて調整
    # @param [in,out] plane Planeオブジェクト
    # @param [in] Image Textureノード
    # @param [in] ratio 何倍のサイズにするか
    # @return なし
    def TextureFixSize(plane,imgnode,ratio):
        
        maxsize = max( imgnode.image.size[0] , imgnode.image.size[1] )
        plane.scale[0] = imgnode.image.size[0] / maxsize * ratio
        plane.scale[1] = imgnode.image.size[1] / maxsize * ratio 
        
    
    # @brief テクスチャをplaneに設定する
    # @param [in,out] plane Planeオブジェクト
    # @param [in] filepath 画像データへのパス
    # @note マテリアルが設定され、Image Textureノードが存在している必要がある
    # @return なし
    def TextureFromFile(plane,filepath):
        ####################
        ## 画像ファイルを読み込み
        pngdata = bpy.data.images.load(filepath = filepath)
    
        ####################
        ## planeオブジェクトのImage Textureノードを取得
        nodetree = plane.material_slots["Material.001"].material.node_tree
        imgnode = nodetree.nodes["Image Texture"]
    
        ####################
        ## Image Textureノードへ画像を設定
        imgnode.image = pngdata
    
        ####################
        ## 張り付けたPlaneオブジェクトのサイズを画像サイズと同じ縦横比に合わせる
        TextureFixSize(plane,imgnode,1)
        
    
    act = bpy.context.active_object
    TextureFromFile(act,'C:/test/lake-6627781_640.jpg')
    

    実行例

    実行前

    実行後

    解説

    画像読み込み、設定

    まず画像ファイルを読み込む

    pngdata = bpy.data.images.load(filepath = filepath)

    次にマテリアルからImage Textureノードを取得する

    nodetree = plane.material_slots["Material.001"].material.node_tree
    imgnode = nodetree.nodes["Image Texture"]

    ノードに画像を設定

    imgnode.image = pngdata

    画像サイズの取得

    Image TextureノードのImageオブジェクトにsizeがある。

    https://docs.blender.org/api/current/bpy.types.ShaderNodeTexImage.html

    Blenderでループするparticleのアニメーションを作成

    1.アニメーションの長さを決める

    例えばアニメーションの長さを 500フレーム とする。この時、

    F == 500
    H == 250 (...500/2)

    と定義する。

    2.Particleを一つ作り、必要な設定をする

    Particleの発生時間を、以下のように設定

    start -(H-1)
    stop H

    3.Particleをコピーし設定

    次に、そのParticleをコピーし、、発生時間を以下のように設定
    start H+1
    stop F+H

    4.フレームとparticleの発生範囲の関係

    500 frameのアニメーションであれば以下のようになる

    まずアニメーションを500フレームに設定

    次にparticleの発生時間を設定し、それをコピーした二つ目のparticleの設定も行う

    particle1 : -249 …. 250
    particle2 : 251 …. 750

    結果