32#include "../../objects/PFont.h"
33#include "../../objects/PColor.h"
36#include "../../utility/PEBLPath.h"
37#include "../../utility/PError.h"
40#include "../../base/Evaluator2.h"
42#include "../../base/Evaluator.h"
47#include <harfbuzz/hb.h>
48#include <harfbuzz/hb-ft.h>
52#if defined(PEBL_OSX) | defined(PEBL_EMSCRIPTEN)
80 const unsigned char * bytes = (
const unsigned char *)(str.c_str());
87 (0x20 <= bytes[0] && bytes[0] <= 0x7E)
95 (0xC2 <= bytes[0] && bytes[0] <= 0xDF) &&
96 (0x80 <= bytes[1] && bytes[1] <= 0xBF)
105 (0xA0 <= bytes[1] && bytes[1] <= 0xBF) &&
106 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
109 ((0xE1 <= bytes[0] && bytes[0] <= 0xEC) ||
112 (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
113 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
117 (0x80 <= bytes[1] && bytes[1] <= 0x9F) &&
118 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
127 (0x90 <= bytes[1] && bytes[1] <= 0xBF) &&
128 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
129 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
132 (0xF1 <= bytes[0] && bytes[0] <= 0xF3) &&
133 (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
134 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
135 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
139 (0x80 <= bytes[1] && bytes[1] <= 0x8F) &&
140 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
141 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
161 long unsigned int size;
162 if(fseek(*file, 0, SEEK_END) == -1){
return -1; }
164 fseek(*file, 0, SEEK_SET);
171 char *buffer = (
char*)malloc(fileSize + 1);
172 fread(buffer,
sizeof(
char),fileSize,*file);
178 unsigned long int fileSize;
179 FILE *file = fopen(path,
"rb");
201 PFont(filename, style, size, fgcolor, bgcolor, aa)
206 FT_Init_FreeType(mLibrary);
221 FT_NewFace(mLibrary,fontname,0,mFace);
225 FT_SetPixelSizes(mFace,0,64);
226 mHBFont = hb_ft_font_create(face,0);
230 while(!mTTF_Font & (tries < 10))
236 SDL_RWops *rw = SDL_RWFromMem(mBuffer,(
int)size);
248 mTTF_Font = TTF_OpenFontRW(rw,0,mFontSize);
257 printf(
"Oh My Goodness, an error : [%s]\n", TTF_GetError());
261#ifndef PEBL_EMSCRIPTEN
262 TTF_SetFontStyle(mTTF_Font, mFontStyle);
281 const FT_Int32& flags = FT_LOAD_DEFAULT;
284 hb_buffer_t *buffer = hb_buffer_create();
287 hb_buffer_set_direction(buffer, HB_DIRECTION_LTR);
294 hb_buffer_set_script(buffer, HB_SCRIPT_THAI);
300 hb_buffer_add_utf16(buffer,
301 (
unsigned short*)(text.c_str()),
305 hb_shape(mHBFont, buffer,
NULL, 0);
307 unsigned int glyph_count = hb_buffer_get_length(buffer);
308 hb_glyph_info_t *glyph_infos = hb_buffer_get_glyph_infos(buffer,
NULL);
309 hb_glyph_position_t *glyph_positions = hb_buffer_get_glyph_positions(buffer,
NULL);
320 mTarget = SDL_CreateTexture(mRenderer,
321 SDL_PIXELFORMAT_ARGB8888,
322 SDL_TEXTUREACCESS_TARGET,
326 SDL_SetTextureBlendMode(mTarget, SDL_BLENDMODE_BLEND);
327 SDL_SetRenderTarget(mRenderer, mTarget);
328 SDL_SetRenderDrawBlendMode(mRenderer, SDL_BLENDMODE_BLEND);
329 SDL_SetRenderDrawColor(mRenderer, 0, 0, 0, 0);
330 SDL_RenderClear(mRenderer);
331 SDL_RenderFillRect(mRenderer,
NULL);
333 int baseline = -rect.y;
336 for (
unsigned int i = 0; i < glyph_count; i++)
338 FT_Load_Glyph( mFace,
339 glyph_infos[i].codepoint,
340 FT_LOAD_RENDER | flags);
345 SDL_QueryTexture(glyph_texture,
NULL,
NULL, &dest.w, &dest.h);
346 dest.x = x + (mFace->glyph->metrics.horiBearingX >> 6) + (glyph_positions[i].x_offset >> 6);
347 dest.y = baseline - (mFace->glyph->metrics.horiBearingY >> 6) - (glyph_positions[i].y_offset >> 6);
350 SDL_RenderCopy(mRenderer, glyph_texture,
NULL, &dest);
352 x += (glyph_positions[i].x_advance >> 6);
354 SDL_DestroyTexture(glyph_texture);
357 hb_buffer_destroy(buffer);
359 SDL_SetRenderTarget(mRenderer,
NULL);
367 Uint32 rmask, gmask, bmask, amask;
368 int req_format = STBI_rgb_alpha;
373 amask = (req_format == STBI_rgb) ? 0 : 0xff000000;
376 if (req_format == STBI_rgb) {
387 SDL_Surface * tmp = SDL_CreateRGBSurfaceFrom( (
void*)(bitmap.buffer),
392 rmask,gmask,bmas,amask);
402 const FT_Bitmap& bitmap,
403 const SDL_Color& color)
405 SDL_Texture* output = SDL_CreateTexture(renderer,
406 SDL_PIXELFORMAT_RGBA8888,
407 SDL_TEXTUREACCESS_STREAMING,
413 SDL_LockTexture(output,
NULL, &buffer, &pitch);
415 unsigned char *src_pixels = bitmap.buffer;
416 unsigned int *target_pixels =
reinterpret_cast<unsigned int*
>(buffer);
418 SDL_PixelFormat* pixel_format = SDL_AllocFormat(SDL_PIXELFORMAT_RGBA8888);
420 for (
int y = 0; y < bitmap.rows; y++)
422 for (
int x = 0; x < bitmap.width; x++)
424 int index = (y * bitmap.width) + x;
426 unsigned int alpha = src_pixels[index];
427 unsigned int pixel_value =
428 SDL_MapRGBA(pixel_format, color.r, color.g, color.b, alpha);
430 target_pixels[index] = pixel_value;
434 SDL_FreeFormat(pixel_format);
435 SDL_UnlockTexture(output);
441 hb_glyph_position_t *glyph_positions,
442 const unsigned int& glyph_count,
445 const FT_Int32& flags = FT_LOAD_DEFAULT)
448 int above_base_line = 0;
449 int below_base_line = 0;
451 for (
unsigned int i = 0; i < glyph_count; i++)
453 FT_Load_Glyph(face, glyph_infos[i].codepoint, FT_LOAD_DEFAULT | flags);
454 width += (glyph_positions[i].x_advance >> 6);
456 (face->glyph->metrics.horiBearingY >> 6) + (glyph_positions[i].y_offset >> 6);
458 if (bearing > above_base_line)
459 above_base_line = bearing;
461 int height_minus_bearing = (face->glyph->metrics.height >> 6) - bearing;
462 if (height_minus_bearing > below_base_line)
463 below_base_line = height_minus_bearing;
467 rect.y = -above_base_line;
469 rect.h = above_base_line + below_base_line;
479 SDL_Color& color = mSDL_FGColor;
482 const int baseline= 0;
484 const int x_start = 0;
495 mSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,
497 (
int)mTextureHeight, 32,
498 rmask, gmask, bmask, amask);
504 hb_buffer_t *buffer = hb_buffer_create();
507 hb_buffer_set_direction(buffer, HB_DIRECTION_LTR);
514 hb_buffer_set_script(buffer, HB_SCRIPT_THAI);
517 hb_buffer_add_utf16(buffer,
518 (
unsigned short*)(text.c_str()),
523 hb_shape(mHBfont, buffer,
NULL, 0);
525 const unsigned int glyph_count = hb_buffer_get_length(buffer);
526 const hb_glyph_info_t *glyph_infos = hb_buffer_get_glyph_infos(buffer,
NULL);
527 const hb_glyph_position_t *glyph_positions = hb_buffer_get_glyph_positions(buffer,
NULL);
530 SDL_SetRenderDrawBlendMode(mRenderer, SDL_BLENDMODE_BLEND);
534 SpanAdditionData addl;
538 for (
unsigned int i = 0; i < glyph_count; i++)
540 FT_Load_Glyph(mFace, glyph_infos[i].codepoint, FT_LOAD_NO_BITMAP);
542 addl.dest.x = x + (glyph_positions[i].x_offset >> 6);
543 addl.dest.y = baseline - (glyph_positions[i].y_offset >> 6);
545 if (mFace->glyph->format == FT_GLYPH_FORMAT_OUTLINE)
547 FT_Raster_Params params;
548 memset(¶ms, 0,
sizeof(params));
549 params.flags = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT;
550 params.gray_spans = DrawSpansCallback;
553 FT_Outline_Render(library, &mFace->glyph->outline, ¶ms);
555 x += (glyph_positions[i].x_advance >> 6);
558 hb_buffer_destroy(buffer);
594 TTF_CloseFont(mTTF_Font);
631 cerr <<
"About to render text [" << text <<
"] with font " << *
this << endl;
634 while(i < text.length())
637 cerr <<
"[" << text[i] <<
"|" << (
unsigned int)(text[i]) <<
"]";
653 std::string toBeRendered = StripText(text);
654 SDL_Surface * tmpSurface =
NULL;
656 if(toBeRendered.length()>maxchars)
658 toBeRendered=toBeRendered.substr(0,maxchars);
661 if(toBeRendered.length() == 0) toBeRendered =
" ";
665 mTexture = DrawTexture(toBeRendered);
672SDL_Surface * PlatformFont::RenderText_old(
const std::wstring & text)
677 cerr <<
"About to render text [" << text <<
"] with font " << *
this << endl;
680 while(i < text.length())
683 cerr <<
"[" << text[i] <<
"|" << (
unsigned int)(text[i]) <<
"]";
700 std::string toBeRendered = StripText(text);
701 SDL_Surface * tmpSurface =
NULL;
703 if(toBeRendered.length()>maxchars)
705 toBeRendered=toBeRendered.substr(0,maxchars);
708 if(toBeRendered.length() == 0) toBeRendered =
" ";
714#ifdef PEBL_EMSCRIPTEN
715 tmpSurface = TTF_RenderText_Blended(mTTF_Font, toBeRendered.c_str(), mSDL_FGColor);
725 tmpSurface = TTF_RenderUTF8_Shaded(mTTF_Font, toBeRendered.c_str(), mSDL_FGColor, mSDL_BGColor);
727 tmpSurface = TTF_RenderText_Shaded(mTTF_Font, toBeRendered.c_str(), mSDL_FGColor, mSDL_BGColor);
736 tmpSurface = TTF_RenderUTF8_Blended(mTTF_Font,toBeRendered.c_str(), mSDL_FGColor);
740 tmpSurface = TTF_RenderText_Blended(mTTF_Font, toBeRendered.c_str(), mSDL_FGColor);
762 string message =
"Unable to render text [" + toBeRendered +
"] in PlatformFont::RenderText. Attempting to render '' instead\n";
767 std::string tmp =
"";
768 tmpSurface = TTF_RenderText_Blended(mTTF_Font, tmp.c_str(), mSDL_FGColor);
776 string message =
"Unable to render text in PlatformFont::RenderText";
785std::string PlatformFont::StripText(
const std::string & text)
791 std::string toBeRendered;
793 for(
unsigned int i = 0; i < text.size(); i++)
804 else if(text[i] == 9)
811 int x = 8*(((int)(toBeRendered.length())+1) /8 + 1 );
812 int diff = (int)x-(
int)(toBeRendered.length());
814 for(
int j = 0; j < diff; j++)
816 toBeRendered.push_back(tmp[0]);
822 toBeRendered.push_back(text[i]);
834 std::string toBeRendered = StripText(text.c_str());
837 TTF_SizeUTF8(mTTF_Font,toBeRendered.c_str(),&width,&height);
839 TTF_SizeText(mTTF_Font,toBeRendered.c_str(),&width,&height);
843 unsigned int uwidth = (
unsigned int)width;
852 TTF_SizeUTF8(mTTF_Font,toBeRendered.c_str(),&width,&height);
854 TTF_SizeText(mTTF_Font,toBeRendered.c_str(),&width,&height);
856 unsigned int uheight = (
unsigned int)height;
867 unsigned int cutoff = 1;
869 while(cutoff < text.size())
873 unsigned int width =
GetTextWidth(text.substr(0,cutoff));
882 return (
unsigned int)(text.size());
888 out <<
"<SDL-Specific Font>" << std::flush;
std::string FindFile(const string &filename)
virtual void SetFontColor(PColor color)
virtual PColor GetBackgroundColor() const
virtual int GetFontStyle() const
virtual void SetBackgroundColor(PColor color)
virtual PColor GetFontColor() const
virtual std::string GetFontFileName() const
std::string mFontFileName
virtual bool GetAntiAliased() const
virtual int GetFontSize() const
void SignalWarning(const std::string &message)
void SignalFatalError(const std::string &message)
SDL_Color PColorToSDLColor(PColor pcolor)
This converts between a PColor and an SDL color.