注册 登录
编程论坛 C++教室

如何正确显示文字?

yahooboby 发布于 2025-04-14 12:14, 542 次点击
最近在学习用SDL2+FreeType2显示中英文本。
但是怎么改都无法正常显示,特来请教。用win10 + vs2019

#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);        //加载外部字体
    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[i], 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,用这个显示多个重复字
只有本站会员才能查看附件,请 登录


帮忙看看改哪里或怎么写才能正常显示文字。
0 回复
1