aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-03-23 12:02:59 -0700
committerAlon Zakai <alonzakai@gmail.com>2012-03-23 12:02:59 -0700
commit6a3c3938cd802db8b034c27b743844735f1b6d28 (patch)
treecb5f38ab6e348984b042177d1a14a451075605b0
parenta7573355dbfafe35ec7620c51dc0d7929b024fb7 (diff)
minimal support for SDL text rendering
-rw-r--r--src/library_sdl.js39
-rwxr-xr-xtests/runner.py6
-rw-r--r--tests/sdl_font.c46
3 files changed, 83 insertions, 8 deletions
diff --git a/src/library_sdl.js b/src/library_sdl.js
index 2f035913..65dbd28c 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -145,6 +145,12 @@ mergeInto(LibraryManager.library, {
};
},
+ // Load SDL color into a CSS-style color specification
+ loadColorToCSS: function(color) {
+ var rgba = {{{ makeGetValue('color', '0', 'i32') }}};
+ return 'rgb(' + (rgba&255) + ',' + ((rgba >> 8)&255) + ',' + ((rgba >> 16)&255) + ')';
+ },
+
makeSurface: function(width, height, flags, usePageCanvas, source) {
flags = flags || 0;
var surf = _malloc(14*Runtime.QUANTUM_SIZE); // SDL_Surface has 14 fields of quantum size
@@ -274,7 +280,7 @@ mergeInto(LibraryManager.library, {
console.log('dumping surface ' + [surfData.surf, surfData.source]);
var image = surfData.ctx.getImageData(0, 0, surfData.width, surfData.height);
var data = image.data;
- var num = Math.min(2, surfData.width, surfData.height);
+ var num = Math.min(surfData.width, surfData.height);
for (var i = 0; i < num; i++) {
console.log(' diagonal ' + i + ':' + [data[i*surfData.width*4 + i*4 + 0], data[i*surfData.width*4 + i*4 + 1], data[i*surfData.width*4 + i*4 + 2], data[i*surfData.width*4 + i*4 + 3]]);
}
@@ -332,10 +338,12 @@ mergeInto(LibraryManager.library, {
if (!surfData.image) {
surfData.image = surfData.ctx.getImageData(0, 0, surfData.width, surfData.height);
- var data = surfData.image.data;
- var num = data.length;
- for (var i = 0; i < num/4; i++) {
- data[i*4+3] = 255; // opacity, as canvases blend alpha
+ if (surf == SDL.screen) {
+ var data = surfData.image.data;
+ var num = data.length;
+ for (var i = 0; i < num/4; i++) {
+ data[i*4+3] = 255; // opacity, as canvases blend alpha
+ }
}
}
if (SDL.defaults.copyOnLock) {
@@ -370,11 +378,12 @@ mergeInto(LibraryManager.library, {
var src = buffer >> 2;
var dst = 0;
while (dst < num) {
+ // TODO: access underlying data buffer and write in 32-bit chunks or more
var val = HEAP32[src]; // This is optimized. Instead, we could do {{{ makeGetValue('buffer', 'dst', 'i32') }}};
data[dst] = val & 0xff;
data[dst+1] = (val >> 8) & 0xff;
data[dst+2] = (val >> 16) & 0xff;
- data[dst+3] = 0xff;
+ data[dst+3] = (val >> 24) & 0xff;
src++;
dst += 4;
}
@@ -702,7 +711,8 @@ mergeInto(LibraryManager.library, {
filename = FS.standardizePath(Pointer_stringify(filename));
var id = SDL.fonts.length;
SDL.fonts.push({
- name: filename // but we don't actually do anything with it..
+ name: filename, // but we don't actually do anything with it..
+ size: size
});
return id;
},
@@ -710,8 +720,21 @@ mergeInto(LibraryManager.library, {
TTF_RenderText_Solid: function(font, text, color) {
// XXX the font and color are ignored
text = Pointer_stringify(text);
- var surf = SDL.makeSurface(20*text.length, 15, 0, false, 'text:' + text); // bogus numbers..
+ var fontData = SDL.fonts[font];
+ var h = fontData.size;
+ var color = SDL.loadColorToCSS(color);
+ var fontString = h + 'px sans-serif';
+ // TODO: use temp context, not screen's, to avoid affecting its performance?
+ var tempCtx = SDL.surfaces[SDL.screen].ctx;
+ tempCtx.save();
+ tempCtx.font = fontString;
+ var w = tempCtx.measureText(text).width;
+ tempCtx.restore();
+ var surf = SDL.makeSurface(w, h, 0, false, 'text:' + text); // bogus numbers..
var surfData = SDL.surfaces[surf];
+ surfData.ctx.fillStyle = color;
+ surfData.ctx.font = fontString;
+ surfData.ctx.textBaseline = 'top';
surfData.ctx.fillText(text, 0, 0);
return surf;
},
diff --git a/tests/runner.py b/tests/runner.py
index c34334ea..66934895 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -6375,6 +6375,12 @@ f.close()
shutil.move(os.path.join(self.get_dir(), basename), basename + '.renamedsoitcannotbefound');
self.run_browser('page.html', '', '/report_result?' + str(width))
+ def test_sdl_font(self):
+ open(os.path.join(self.get_dir(), 'sdl_font.c'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl_font.c')).read()))
+
+ Popen(['python', EMCC, os.path.join(self.get_dir(), 'sdl_font.c'), '-o', 'page.html']).communicate()
+ self.run_browser('page.html', '', '/report_result?80')
+
def test_worker(self):
# Test running in a web worker
output = Popen(['python', EMCC, path_from_root('tests', 'hello_world_worker.cpp'), '-o', 'worker.js'], stdout=PIPE, stderr=PIPE).communicate()
diff --git a/tests/sdl_font.c b/tests/sdl_font.c
new file mode 100644
index 00000000..f4f26355
--- /dev/null
+++ b/tests/sdl_font.c
@@ -0,0 +1,46 @@
+#include <stdio.h>
+#include <SDL/SDL.h>
+#include <SDL/SDL_ttf.h>
+#include <emscripten.h>
+
+int main() {
+ SDL_Init(SDL_INIT_VIDEO);
+ SDL_Surface *screen = SDL_SetVideoMode(600, 450, 32, SDL_HWSURFACE);
+
+ printf("Init: %d\n", TTF_Init());
+
+ TTF_Font *font = TTF_OpenFont("myfont.ttf", 40);
+ printf("Font: %p\n", font);
+
+ SDL_Color color = { 0xff, 0x99, 0x00, 0x77 };
+
+ SDL_Surface *text = TTF_RenderText_Solid(font, "hello orange world", color);
+ SDL_LockSurface(text);
+ int sum = 0;
+ for (int i = 0; i < text->h; i++) {
+ sum += *((char*)text->pixels + i*text->w*4 + i*4 + 0);
+ }
+ printf("Sum: %d\n", sum);
+ SDL_UnlockSurface(text);
+
+ SDL_Color color2 = { 0xbb, 0, 0xff, 0 };
+ SDL_Surface *text2 = TTF_RenderText_Solid(font, "a second line, purple", color2);
+
+ // render
+ SDL_Rect dest = { 0, 50, 0, 0 };
+ SDL_BlitSurface (text, NULL, screen, NULL);
+ dest.y = 100;
+ SDL_BlitSurface (text2, NULL, screen, &dest);
+
+ SDL_Flip(screen);
+
+ printf("you should see two lines of text in different colors.\n");
+
+ SDL_Quit();
+
+ int result = sum;
+ REPORT_RESULT();
+
+ return 0;
+}
+