PEBL 2.2
Psychology Experiment Building Language - Cross-platform psychological experiment development system
PlatformFont_RTL.cpp File Reference
#include "PlatformFont.h"
#include "../../objects/PFont.h"
#include "../../objects/PColor.h"
#include "../../utility/PEBLPath.h"
#include "../../utility/PError.h"
#include "../../base/Evaluator.h"
#include "SDL.h"
#include "SDL_ttf.h"
#include "SDL_rwops.h"
#include <stdio.h>
#include <iostream>

Go to the source code of this file.

Functions

bool is_utf8 (std::string str)
 
long unsigned int getFileSize (FILE **file)
 
char * getFileBuffer (FILE **file, unsigned int fileSize)
 
unsigned long int readFileToMemory (const char path[], char **buffr)
 
void RenderTexture (const std::wstring &text)
 
SDL_Surface * CreateSurfaceFromFT_Bitmap (const FT_Bitmap &bitmap)
 
SDL_Texture * CreateTextureFromFT_Bitmap (SDL_Renderer *renderer, const FT_Bitmap &bitmap, const SDL_Color &color)
 
void CalculateSurfaceBound (hb_glyph_info_t *glyph_infos, hb_glyph_position_t *glyph_positions, const unsigned int &glyph_count, const FT_Face &face, SDL_Rect &rect, const FT_Int32 &flags=FT_LOAD_DEFAULT)
 
void DrawTextHB (conts std::wstring &Text)
 

Function Documentation

◆ CalculateSurfaceBound()

void CalculateSurfaceBound ( hb_glyph_info_t *  glyph_infos,
hb_glyph_position_t *  glyph_positions,
const unsigned int &  glyph_count,
const FT_Face &  face,
SDL_Rect &  rect,
const FT_Int32 &  flags = FT_LOAD_DEFAULT 
)

Definition at line 440 of file PlatformFont_RTL.cpp.

446{
447 int width = 0;
448 int above_base_line = 0;
449 int below_base_line = 0;
450
451 for (unsigned int i = 0; i < glyph_count; i++)
452 {
453 FT_Load_Glyph(face, glyph_infos[i].codepoint, FT_LOAD_DEFAULT | flags);
454 width += (glyph_positions[i].x_advance >> 6);
455 int bearing =
456 (face->glyph->metrics.horiBearingY >> 6) + (glyph_positions[i].y_offset >> 6);
457
458 if (bearing > above_base_line)
459 above_base_line = bearing;
460
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;
464 }
465
466 rect.x = 0;
467 rect.y = -above_base_line;
468 rect.w = width;
469 rect.h = above_base_line + below_base_line;
470
471}

Referenced by RenderTexture().

◆ CreateSurfaceFromFT_Bitmap()

SDL_Surface * CreateSurfaceFromFT_Bitmap ( const FT_Bitmap &  bitmap)

Definition at line 365 of file PlatformFont_RTL.cpp.

366{
367 Uint32 rmask, gmask, bmask, amask;
368 int req_format = STBI_rgb_alpha;
369
370 rmask = 0x000000ff;
371 gmask = 0x0000ff00;
372 bmask = 0x00ff0000;
373 amask = (req_format == STBI_rgb) ? 0 : 0xff000000;
374
375 int depth, pitch;
376 if (req_format == STBI_rgb) {
377 depth = 24;
378 pitch = 3*width; // 3 bytes per pixel * pixels per row
379 } else { // STBI_rgb_alpha (RGBA)
380 depth = 32;
381 pitch = 4*width;
382 }
383
384 //we may have to translate buffer to pixels here.
385
386
387 SDL_Surface * tmp = SDL_CreateRGBSurfaceFrom( (void*)(bitmap.buffer), // dest_buffer from CopyTo
388 bitmap.width, // in pixels
389 bitmap.height, // in pixels
390 depth, // in bits, so should be dest_depth * 8
391 pitch, // dest_row_span from CopyTo
392 rmask,gmask,bmas,amask); // RGBA masks, see docs
393
394 return tmp;
395}

Referenced by RenderTexture().

◆ CreateTextureFromFT_Bitmap()

SDL_Texture * CreateTextureFromFT_Bitmap ( SDL_Renderer *  renderer,
const FT_Bitmap &  bitmap,
const SDL_Color &  color 
)

Definition at line 401 of file PlatformFont_RTL.cpp.

404{
405 SDL_Texture* output = SDL_CreateTexture(renderer,
406 SDL_PIXELFORMAT_RGBA8888,
407 SDL_TEXTUREACCESS_STREAMING,
408 bitmap.width,
409 bitmap.rows);
410
411 void *buffer;
412 int pitch;
413 SDL_LockTexture(output, NULL, &buffer, &pitch);
414
415 unsigned char *src_pixels = bitmap.buffer;
416 unsigned int *target_pixels = reinterpret_cast<unsigned int*>(buffer);
417
418 SDL_PixelFormat* pixel_format = SDL_AllocFormat(SDL_PIXELFORMAT_RGBA8888);
419
420 for (int y = 0; y < bitmap.rows; y++)
421 {
422 for (int x = 0; x < bitmap.width; x++)
423 {
424 int index = (y * bitmap.width) + x;
425
426 unsigned int alpha = src_pixels[index];
427 unsigned int pixel_value =
428 SDL_MapRGBA(pixel_format, color.r, color.g, color.b, alpha);
429
430 target_pixels[index] = pixel_value;
431 }
432 }
433
434 SDL_FreeFormat(pixel_format);
435 SDL_UnlockTexture(output);
436
437 return output;
438}
#define NULL
Definition BinReloc.cpp:317

References NULL.

◆ DrawTextHB()

void DrawTextHB ( conts std::wstring &  Text)

Definition at line 474 of file PlatformFont_RTL.cpp.

475{
476
477 //These are the arguments originally passed in to the function:
478 //const SDL_Color& color,
479 SDL_Color& color = mSDL_FGColor;
480
481 //const int& baseline,
482 const int baseline= 0;
483 //const int& x_start,
484 const int x_start = 0;
485 //const FT_Face& face //===mFace
486 //hb_font_t* hb_font, //== mHBFont
487 //SDL_Renderer*& renderer //= mRenderer
488
489 //this will render directly onto wherever the renderer is currently pointing.
490 //This might be smart, but labels and textboxes _expect_ a tmpSurface to be returned.
491 //and so we need to create one here to use.
492
493
494
495 mSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,
496 (int)mTextureWidth,
497 (int)mTextureHeight, 32,
498 rmask, gmask, bmask, amask);
499
500
501 if(!mSurface) PError::SignalFatalError("Surface not created in TextBox::RenderText.");
502
503
504 hb_buffer_t *buffer = hb_buffer_create();
505
506 //This could be HB_DIRECTION_LTR; HB_DIRECTION_RTL; HB_DIRECTION_TTB, B_DIRECTION_BTT, HB_DIRECTION_INVALID;
507 hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); //hardcode as LTR for testing
508
509 //could be HB_SCRIPT_ARABIC
510 // HB_SCRIPT_LATIN
511 // HB_SCRIPT_INVALID
512 // HB_SCRIPT_UNKNOWN, etc.
513 //could use hb_scirpt_from_string to select this:
514 hb_buffer_set_script(buffer, HB_SCRIPT_THAI);
515
516
517 hb_buffer_add_utf16(buffer,
518 (unsigned short*)(text.c_str()),
519 text.length(),
520 0,
521 text.length());
522
523 hb_shape(mHBfont, buffer, NULL, 0);
524
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);
528
529 //This renders directly onto the surface; it does not produce a surface.
530 SDL_SetRenderDrawBlendMode(mRenderer, SDL_BLENDMODE_BLEND);
531
532 int x = x_start;
533
534 SpanAdditionData addl;
535
536 addl.color = color;
537
538 for (unsigned int i = 0; i < glyph_count; i++)
539 {
540 FT_Load_Glyph(mFace, glyph_infos[i].codepoint, FT_LOAD_NO_BITMAP);
541
542 addl.dest.x = x + (glyph_positions[i].x_offset >> 6);
543 addl.dest.y = baseline - (glyph_positions[i].y_offset >> 6);
544
545 if (mFace->glyph->format == FT_GLYPH_FORMAT_OUTLINE)
546 {
547 FT_Raster_Params params;
548 memset(&params, 0, sizeof(params));
549 params.flags = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT;
550 params.gray_spans = DrawSpansCallback;
551 params.user = &addl;
552
553 FT_Outline_Render(library, &mFace->glyph->outline, &params);
554 }//No fallback
555 x += (glyph_positions[i].x_advance >> 6);
556 }
557
558 hb_buffer_destroy(buffer);
559}
void SignalFatalError(const std::string &message)

References NULL, and PError::SignalFatalError().

◆ getFileBuffer()

char * getFileBuffer ( FILE **  file,
unsigned int  fileSize 
)

Definition at line 170 of file PlatformFont_RTL.cpp.

170 {
171 char *buffer = (char*)malloc(fileSize + 1);
172 fread(buffer, sizeof(char),fileSize,*file);
173 return buffer;
174}

Referenced by readFileToMemory().

◆ getFileSize()

long unsigned int getFileSize ( FILE **  file)

Definition at line 160 of file PlatformFont_RTL.cpp.

160 {
161 long unsigned int size;
162 if(fseek(*file, 0, SEEK_END) == -1){ return -1; }
163 size = ftell(*file);
164 fseek(*file, 0, SEEK_SET);
165 return size;
166}

Referenced by readFileToMemory().

◆ is_utf8()

bool is_utf8 ( std::string  str)

Definition at line 73 of file PlatformFont_RTL.cpp.

74{
75
76
77 if(str.length()==0)
78 return false;
79
80 const unsigned char * bytes = (const unsigned char *)(str.c_str());
81 while(*bytes)
82 {
83 if( (// ASCII
84 bytes[0] == 0x09 ||
85 bytes[0] == 0x0A ||
86 bytes[0] == 0x0D ||
87 (0x20 <= bytes[0] && bytes[0] <= 0x7E)
88 )
89 ) {
90 bytes += 1;
91 continue;
92 }
93
94 if( (// non-overlong 2-byte
95 (0xC2 <= bytes[0] && bytes[0] <= 0xDF) &&
96 (0x80 <= bytes[1] && bytes[1] <= 0xBF)
97 )
98 ) {
99 bytes += 2;
100 continue;
101 }
102
103 if( (// excluding overlongs
104 bytes[0] == 0xE0 &&
105 (0xA0 <= bytes[1] && bytes[1] <= 0xBF) &&
106 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
107 ) ||
108 (// straight 3-byte
109 ((0xE1 <= bytes[0] && bytes[0] <= 0xEC) ||
110 bytes[0] == 0xEE ||
111 bytes[0] == 0xEF) &&
112 (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
113 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
114 ) ||
115 (// excluding surrogates
116 bytes[0] == 0xED &&
117 (0x80 <= bytes[1] && bytes[1] <= 0x9F) &&
118 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
119 )
120 ) {
121 bytes += 3;
122 continue;
123 }
124
125 if( (// planes 1-3
126 bytes[0] == 0xF0 &&
127 (0x90 <= bytes[1] && bytes[1] <= 0xBF) &&
128 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
129 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
130 ) ||
131 (// planes 4-15
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)
136 ) ||
137 (// plane 16
138 bytes[0] == 0xF4 &&
139 (0x80 <= bytes[1] && bytes[1] <= 0x8F) &&
140 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
141 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
142 )
143 ) {
144 bytes += 4;
145 continue;
146 }
147
148 return false;
149 }
150
151 return true;
152}

Referenced by PEBLUtility::DetectScript().

◆ readFileToMemory()

unsigned long int readFileToMemory ( const char  path[],
char **  buffr 
)

Definition at line 176 of file PlatformFont_RTL.cpp.

176 {
177
178 unsigned long int fileSize;
179 FILE *file = fopen(path, "rb");
180 if(file != NULL){
181 fileSize = getFileSize(&file);
182 //cerr << "FIlesize: " << fileSize << endl;
183 char* buff = getFileBuffer(&file,(unsigned int)fileSize);
184
185
186 (*buffr) = buff;
187
188
189 fclose(file);
190 return fileSize;
191 }else{
192 *buffr = NULL;
193 return 0;
194 }
195}
char * getFileBuffer(FILE **file, unsigned int fileSize)
long unsigned int getFileSize(FILE **file)

References getFileBuffer(), getFileSize(), and NULL.

◆ RenderTexture()

void RenderTexture ( const std::wstring &  text)

Definition at line 272 of file PlatformFont_RTL.cpp.

273{
274 // const SDL_Color& color, //==mSDL_FGColor
275 // const Font& font, // combines mFace and mHBFont
276 // SDL_Renderer*& renderer, //==mRenderer
277
278 // SDL_Texture*& target, //mTarget???
279 // SDL_Rect& rect)
280
281 const FT_Int32& flags = FT_LOAD_DEFAULT;
282
283
284 hb_buffer_t *buffer = hb_buffer_create();
285
286 //This could be HB_DIRECTION_LTR; HB_DIRECTION_RTL; HB_DIRECTION_TTB, B_DIRECTION_BTT, HB_DIRECTION_INVALID;
287 hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); //hardcode as LTR for testing
288
289 //could be HB_SCRIPT_ARABIC
290 // HB_SCRIPT_LATIN
291 // HB_SCRIPT_INVALID
292 // HB_SCRIPT_UNKNOWN, etc.
293 //could use hb_scirpt_from_string to select this:
294 hb_buffer_set_script(buffer, HB_SCRIPT_THAI);
295
296
297
298
299
300 hb_buffer_add_utf16(buffer,
301 (unsigned short*)(text.c_str()),
302 text.length(),
303 0, text.length());
304
305 hb_shape(mHBFont, buffer, NULL, 0);
306
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);
310
311 SDL_Rect rect; //get size of rendering.
312
313 CalculateSurfaceBound(glyph_infos,
314 glyph_positions,
315 glyph_count,
316 mFace,
317 rect,
318 flags);
319
320 mTarget = SDL_CreateTexture(mRenderer,
321 SDL_PIXELFORMAT_ARGB8888,
322 SDL_TEXTUREACCESS_TARGET,
323 rect.w,
324 rect.h);
325
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);
332
333 int baseline = -rect.y;
334 int x = 0;
335
336 for (unsigned int i = 0; i < glyph_count; i++)
337 {
338 FT_Load_Glyph( mFace,
339 glyph_infos[i].codepoint,
340 FT_LOAD_RENDER | flags);
341
342 SDL_Surface* glyph_surface = CreateSurfaceFromFT_Bitmap(mFace->glyph->bitmap);//used to take a color--maybe this is needed?
343
344 SDL_Rect dest;
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);
348
349
350 SDL_RenderCopy(mRenderer, glyph_texture, NULL, &dest);
351
352 x += (glyph_positions[i].x_advance >> 6);
353
354 SDL_DestroyTexture(glyph_texture);
355 }
356
357 hb_buffer_destroy(buffer);
358
359 SDL_SetRenderTarget(mRenderer, NULL);
360 return
361}
void CalculateSurfaceBound(hb_glyph_info_t *glyph_infos, hb_glyph_position_t *glyph_positions, const unsigned int &glyph_count, const FT_Face &face, SDL_Rect &rect, const FT_Int32 &flags=FT_LOAD_DEFAULT)
SDL_Surface * CreateSurfaceFromFT_Bitmap(const FT_Bitmap &bitmap)

References CalculateSurfaceBound(), CreateSurfaceFromFT_Bitmap(), and NULL.