飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 2046|回复: 2

[求助] 无法正确显示中文!

[复制链接]
  • TA的每日心情
    奋斗
    2025-1-14 00:13
  • 签到天数: 2658 天

    [LV.Master]伴坛终老

    发表于 2025-5-1 21:06:55 | 显示全部楼层 |阅读模式
    20飘云币
    有哪位大佬熟悉SDL2+FreeType2的吗?
    最近在学习用SDL2+FreeType2显示中英文本。
    但是怎么改都无法正常显示,特来请教。用win10 + vs2019

    #main.cpp

    #define _CRT_SECURE_NO_WARNINGS
    #include <windows.h>
    #include <iOStream>
    #include <SDL.h>
    #include <ft2build.h>
    #include FT_FREETYPE_H
    #include "iconv.h"
    #pragma comment(lib, "SDL2maind.lib")
    #pragma comment(lib, "SDL2-staticd.lib")
    #pragma comment(lib, "SDL2.lib")
    #pragma comment(lib, "freetyped.lib")
    #pragma comment(lib, "iconv-static_Debug.lib")
    #pragma comment(lib, "winmm.lib")
    #pragma comment(lib, "imm32.lib")
    #pragma comment(lib, "version.lib")
    #pragma comment(lib, "setupapi.lib")

    int L2U(const char* input, size_t charInPutLen);
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
    void ft2_1(const char* text);
    void DrawBitmap(FT_Bitmap bm, int x, int y, SDL_Surface* target);
    SDL_Window* window = nullptr;
    SDL_Renderer* renderer = nullptr;
    SDL_Texture* texture = nullptr;
    SDL_Surface* surface = nullptr;
    uint32_t output[1024] = { 0 };
    int fontsize = 48;  //字体大小

    int main(int argc, char* argv[]) {
        //初始化SDL
        SDL_Init(SDL_INIT_VIDEO);
        //创建一个窗口
        window = SDL_CreateWindow("FreeType2 with SDL2",
            100,
            100,
            640, 480,
            SDL_WINDOW_SHOWN);
        //获得surface
        surface = SDL_GetWindowSurface(window);
        //创建渲染器
        renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
        SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);  //设置背景颜色为蓝色
        SDL_RenderClear(renderer);    //清理屏幕
        SDL_RenderPresent(renderer);  //刷新屏幕
        SDL_Event event = { 0 };
        MSG msg = { 0 };
            //我想正常显示下面的文本
        const char* text = "Hello!中文!!";  //定义文本内容
        ft2_1(text);
        while (GetMessage(&msg, NULL, 0, 0)) {
            if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE) {
                // 按下 Esc 键,退出程序
                PostQuitMessage(0);
                break;
            }
            while (SDL_PollEvent(&event)) {  /*监检鼠标事件*/
                if (event.type == SDL_QUIT) {  //检测到关闭事件,就是点击程序右上角的X
                    PostQuitMessage(0);
                    break;
                }
                break;
            }
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        SDL_DestroyWindow(window);
        SDL_DestroyRenderer(renderer);
        SDL_DestroyTexture(texture);
        SDL_Quit();
        return 0;
    }

    int L2U(const char* input, size_t charInPutLen) {
        size_t output_size = 1024;
        iconv_t cd = iconv_open("UCS-4-INTERNAL", "GBK");  //设置为UNICODE
        memset(&output, 0, output_size);
        char* tmp = (char*)output;
        iconv(cd, &input, &charInPutLen, &tmp, &output_size);
        iconv_close(cd);
        return (1024 - output_size) / 4;
    }

    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
        switch (message) {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        }
        return DefWindowProc(hwnd, message, wParam, lParam);
    }

    void ft2_1(const char* text) {
        FT_Library    lib;
        FT_Face       face;
        int x = 50, y = 100;  //设置开始显示的坐标
        FT_Init_FreeType(&lib);
        FT_New_Face(lib, "GB2312.ttf", 0, &face);        //加载外部字体GB2312.tff
        FT_Select_Charmap(face, FT_ENCODING_UNICODE);    //指定字符编码集UNICODE
        FT_Set_Pixel_Sizes(face, 0, (FT_UInt)fontsize);  //设置字体大小
        size_t len = strlen((char*)text);
        size_t count = L2U((char*)text, len);
        for (size_t i = 0; i < count; ++i) {
            FT_Load_Char(face, output, FT_LOAD_RENDER);
            DrawBitmap(face->glyph->bitmap,
                x + face->glyph->bitmap_left,
                y - face->glyph->bitmap_top,
                surface);
            x += face->glyph->advance.x >> 6;  //移动到下一个字符的位置
        }
        FT_Done_Face(face);
        FT_Done_FreeType(lib);
    }

    //------主要是这个函数------------
    void DrawBitmap(FT_Bitmap bitmap, int x, int y, SDL_Surface* surface) {
        ////创建SDL表面-1,用这个不显示任何字体,只有白方框没有文字
        //SDL_Surface* glyphSurface = SDL_CreateRGBSurfaceFrom(
        //    bitmap.buffer,
        //    bitmap.width,
        //    bitmap.rows,
        //    8,
        //    bitmap.pitch,
        //    0, 0, 0, 0xFF);

        //创建SDL表面-2,用这个显示多个重复字
        SDL_Surface* glyphSurface = SDL_CreateRGBSurfaceWithFormatFrom(
            bitmap.buffer,
            bitmap.width,
            bitmap.rows,
            8,
            bitmap.pitch * 4,
            SDL_PIXELFORMAT_ARGB8888);

        SDL_Rect dest = { x, y, 0, 0 };
        SDL_BlitSurface(glyphSurface, nullptr, surface, &dest);
        texture = SDL_CreateTextureFromSurface(renderer, glyphSurface);
        SDL_RenderCopy(renderer, texture, nullptr, &dest);
        SDL_RenderPresent(renderer);
        SDL_FreeSurface(glyphSurface);
    }

    1-用SDL_CreateRGBSurfaceFrom函数-//创建SDL表面-1,用这个不显示任何字体,只有白方框没有文字


    2-用SDL_CreateRGBSurfaceWithFormatFrom函数-//创建SDL表面-2,用这个显示多个重复字


    大佬帮忙看看改哪里或怎么写才能正常显示文字。


    附件: 您需要 登录 才可以下载或查看,没有账号?加入我们
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2025-1-14 11:07
  • 签到天数: 1337 天

    [LV.10]以坛为家III

    发表于 2025-5-1 22:05:00 | 显示全部楼层
    试试问一下 AI

    点评

    问过AI,AI答非所问。没有给出关键问题的地方  详情 回复 发表于 7 天前
    PYG19周年生日快乐!
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2025-1-14 00:13
  • 签到天数: 2658 天

    [LV.Master]伴坛终老

     楼主| 发表于 7 天前 | 显示全部楼层

    问过AI,AI答非所问。没有给出关键问题的地方

    PYG19周年生日快乐!
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表