mirror of
https://github.com/switchbrew/switch-examples.git
synced 2025-06-21 13:22:40 +02:00
shared_font example now displays a string.
This commit is contained in:
parent
74b4d912a5
commit
db568881ea
@ -1,4 +1,5 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
|
||||||
@ -7,24 +8,87 @@
|
|||||||
|
|
||||||
//See also libnx pl.h.
|
//See also libnx pl.h.
|
||||||
|
|
||||||
//TODO: Finish this.
|
|
||||||
|
|
||||||
//This requires the switch-freetype package.
|
//This requires the switch-freetype package.
|
||||||
//Freetype code here is based on the example code from freetype docs.
|
//Freetype code here is based on the example code from freetype docs.
|
||||||
|
|
||||||
|
static u32 framebuf_width=0;
|
||||||
|
|
||||||
|
//Note that this doesn't handle any blending.
|
||||||
|
void draw_glyph(FT_Bitmap* bitmap, u32* framebuf, u32 x, u32 y)
|
||||||
|
{
|
||||||
|
u32 framex, framey;
|
||||||
|
u32 tmpx, tmpy;
|
||||||
|
u8* imageptr = bitmap->buffer;
|
||||||
|
|
||||||
|
if (bitmap->pixel_mode!=FT_PIXEL_MODE_GRAY) return;
|
||||||
|
|
||||||
|
for (tmpy=0; tmpy<bitmap->rows; tmpy++)
|
||||||
|
{
|
||||||
|
for (tmpx=0; tmpx<bitmap->width; tmpx++)
|
||||||
|
{
|
||||||
|
framex = x + tmpx;
|
||||||
|
framey = y + tmpy;
|
||||||
|
|
||||||
|
framebuf[framey * framebuf_width + framex] = RGBA8_MAXALPHA(imageptr[tmpx], imageptr[tmpx], imageptr[tmpx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
imageptr+= bitmap->pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Note that this doesn't handle newline, etc.
|
||||||
|
//str is UTF-8.
|
||||||
|
void draw_text(FT_Face face, u32* framebuf, u32 x, u32 y, const uint8_t* str)
|
||||||
|
{
|
||||||
|
FT_Error ret=0;
|
||||||
|
FT_UInt glyph_index;
|
||||||
|
FT_GlyphSlot slot = face->glyph;
|
||||||
|
|
||||||
|
u32 i;
|
||||||
|
u32 str_size = strlen((const char*)str);
|
||||||
|
uint32_t tmpchar;
|
||||||
|
ssize_t unitcount=0;
|
||||||
|
|
||||||
|
for (i = 0; i < str_size; )
|
||||||
|
{
|
||||||
|
unitcount = decode_utf8 (&tmpchar, &str[i]);
|
||||||
|
if (unitcount <= 0) break;
|
||||||
|
i+= unitcount;
|
||||||
|
|
||||||
|
glyph_index = FT_Get_Char_Index(face, tmpchar);
|
||||||
|
//If using multiple fonts, you could check for glyph_index==0 here and attempt using the FT_Face for the other fonts with FT_Get_Char_Index.
|
||||||
|
|
||||||
|
ret = FT_Load_Glyph(
|
||||||
|
face, /* handle to face object */
|
||||||
|
glyph_index, /* glyph index */
|
||||||
|
FT_LOAD_DEFAULT);
|
||||||
|
|
||||||
|
if (ret==0)
|
||||||
|
{
|
||||||
|
ret = FT_Render_Glyph( face->glyph, /* glyph slot */
|
||||||
|
FT_RENDER_MODE_NORMAL); /* render mode */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret) return;
|
||||||
|
|
||||||
|
draw_glyph(&slot->bitmap, framebuf, x + slot->bitmap_left, y - slot->bitmap_top);
|
||||||
|
|
||||||
|
x += slot->advance.x >> 6;
|
||||||
|
y += slot->advance.y >> 6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
Result rc=0;
|
Result rc=0;
|
||||||
//u32* framebuf;
|
u32* framebuf;
|
||||||
u32 i;
|
|
||||||
|
|
||||||
u64 LanguageCode=0;
|
u64 LanguageCode=0;
|
||||||
PlFontData fonts[PlSharedFontType_Total];
|
PlFontData fonts[PlSharedFontType_Total];
|
||||||
size_t total_fonts=0;
|
size_t total_fonts=0;
|
||||||
FT_Error ret;
|
FT_Error ret=0, libret=0, faceret=0;
|
||||||
FT_Library library;
|
FT_Library library;
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
FT_UInt glyph_index;
|
|
||||||
|
|
||||||
gfxInitDefault();
|
gfxInitDefault();
|
||||||
consoleInit(NULL);
|
consoleInit(NULL);
|
||||||
@ -46,24 +110,21 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
if (R_FAILED(rc)) printf("plGetSharedFont() failed: 0x%x\n", rc);
|
if (R_FAILED(rc)) printf("plGetSharedFont() failed: 0x%x\n", rc);
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc))
|
|
||||||
{
|
|
||||||
printf("total_fonts: %lu\n", total_fonts);
|
|
||||||
|
|
||||||
for (i=0; i<total_fonts; i++) printf("[%u] type=%u\n", i, fonts[i].type);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = FT_Init_FreeType(&library);
|
ret = FT_Init_FreeType(&library);
|
||||||
|
libret = ret;
|
||||||
if (ret) printf("FT_Init_FreeType() failed: %d\n", ret);
|
if (ret) printf("FT_Init_FreeType() failed: %d\n", ret);
|
||||||
|
|
||||||
if (ret==0)
|
if (ret==0)
|
||||||
{
|
{
|
||||||
|
//Use the second font. You may want to use all fonts, if you want to support non-{Japan, US and Europe} fonts.
|
||||||
|
//TODO: Probably should use PlSharedFontType_Standard explicitly, instead of assuming it's fonts[1].
|
||||||
ret = FT_New_Memory_Face( library,
|
ret = FT_New_Memory_Face( library,
|
||||||
fonts[0].address, /* first byte in memory */
|
fonts[1].address, /* first byte in memory */
|
||||||
fonts[0].size, /* size in bytes */
|
fonts[1].size, /* size in bytes */
|
||||||
0, /* face_index */
|
0, /* face_index */
|
||||||
&face);
|
&face);
|
||||||
|
|
||||||
|
faceret = ret;
|
||||||
if (ret) printf("FT_New_Memory_Face() failed: %d\n", ret);
|
if (ret) printf("FT_New_Memory_Face() failed: %d\n", ret);
|
||||||
|
|
||||||
if (ret==0)
|
if (ret==0)
|
||||||
@ -71,24 +132,23 @@ int main(int argc, char **argv)
|
|||||||
ret = FT_Set_Char_Size(
|
ret = FT_Set_Char_Size(
|
||||||
face, /* handle to face object */
|
face, /* handle to face object */
|
||||||
0, /* char_width in 1/64th of points */
|
0, /* char_width in 1/64th of points */
|
||||||
16*64, /* char_height in 1/64th of points */
|
8*64, /* char_height in 1/64th of points */
|
||||||
300, /* horizontal device resolution */
|
300, /* horizontal device resolution */
|
||||||
300); /* vertical device resolution */
|
300); /* vertical device resolution */
|
||||||
|
|
||||||
if (ret) printf("FT_Set_Char_Size() failed: %d\n", ret);
|
if (ret) printf("FT_Set_Char_Size() failed: %d\n", ret);
|
||||||
|
|
||||||
if (ret==0) glyph_index = FT_Get_Char_Index(face, 'A');//TODO: Load charcode from string.
|
|
||||||
|
|
||||||
FT_Done_Face(face);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FT_Done_FreeType(library);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
plExit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc) && ret==0)
|
||||||
|
{
|
||||||
|
//Switch to using regular framebuffer.
|
||||||
|
consoleClear();
|
||||||
|
gfxSetMode(GfxMode_LinearDouble);
|
||||||
|
}
|
||||||
|
|
||||||
while(appletMainLoop())
|
while(appletMainLoop())
|
||||||
{
|
{
|
||||||
//Scan all the inputs. This should be done once for each frame
|
//Scan all the inputs. This should be done once for each frame
|
||||||
@ -99,14 +159,19 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
if (kDown & KEY_PLUS) break; // break in order to return to hbmenu
|
if (kDown & KEY_PLUS) break; // break in order to return to hbmenu
|
||||||
|
|
||||||
//u32 width, height;
|
framebuf = (u32*) gfxGetFramebuffer(&framebuf_width, NULL);
|
||||||
//framebuf = (u32*) gfxGetFramebuffer((u32*)&width, (u32*)&height);
|
|
||||||
|
if (R_SUCCEEDED(rc) && ret==0) draw_text(face, framebuf, 64, 64, (const uint8_t*)"The quick brown fox jumps over the lazy dog. ファイル");
|
||||||
|
|
||||||
gfxFlushBuffers();
|
gfxFlushBuffers();
|
||||||
gfxSwapBuffers();
|
gfxSwapBuffers();
|
||||||
gfxWaitForVsync();
|
gfxWaitForVsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (faceret==0) FT_Done_Face(face);
|
||||||
|
if (libret==0) FT_Done_FreeType(library);
|
||||||
|
|
||||||
|
plExit();
|
||||||
gfxExit();
|
gfxExit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user