diff --git a/demo/data/fonts/blackcha.txt b/demo/data/fonts/blackcha.txt new file mode 100644 index 0000000..99305e4 --- /dev/null +++ b/demo/data/fonts/blackcha.txt @@ -0,0 +1,29 @@ +Black Chancery font +version of 11/19/91 by Earl Allen/Doug Miles +(Includes both PostScript and TrueType outlines) +----------------- + +Black Chancery is a calligraphic outline font based on the public domain bitmap font of the same name. It's a good looking and useful display font, lending itself well to many occasions. And a suitable companion to Black Chancery Italic. + +Black Chancery began, several years ago, as a modification of Bill Horton�s lovely FancyChancery 24 point bitmap, which had random dots missing from within the letters to give the effect of snow falling in front of them. (Rather like his Palazzo Grey font, part of Casady�s bitmap Fluent Fonts). Doug Miles filled in the dots, did some restyling, made five additional large point sizes, and gave it a new name. + +Earl Allen of Altsys Corp. used Fontographer 3.2 to autotrace the BlackChancery bitmaps to make PostScript Type 1 outlines, cleaned them up, adjusted character spacing and added kerning pairs. Doug Miles further cleaned-up the outlines, removing unneeded control points, adjusted the height and baseline positions of most characters, resized some of them, added accented letters and other option characters. He converted the numbers to "old style" figures, probably more appropriate for this font. + +(Note that Bill Horton has made his own public domain PostScript version of BlackChancery, considerably restyled and called MacHumaine. It's more angular looking, more faithful to actual hand-done broad-pen calligraphy. This extended the remarkable uncoordinated collaborative effort full circle, from his FancyChancery bitmaps, to Doug's BlackChancery version, to PostScript outlines by Marion Delahan, and back to Bill!) + +There is an optional lowercase j available by pressing Option-j, if you prefer a different style. There are now ligatures of ct and st at Option-comma and Option-period, and of course the ligatures of fi and fl are in their standard locations at Option-5 and Option-6. + +BlackChancery is great for headlines, letterheads, greeting cards. Wherever used, it adds an old-world elegance to your printed page. + + +11/19/91 Revisons: +Replaced all accented characters with composites +Changed ', ", �, a, d, g, q; f, �, �; �, �; reduced size of most accents by 15%. +Moved to right by 5 ems: p (1250 ems to the em-square) +Moved to right by 10 ems: i, �, l, t, u +Moved to right by 15 ems: b, h, k, m, n, r +Moved to left and narrowed by 30 ems: x +Moved to left and narrowed by 70 ems: v, w, y +Added 50 ems of leading, which had been 0. +Fixed a lot of little things here and there in conjunction with making the italic version. + diff --git a/demo/data/fonts/blackcry.ttf b/demo/data/fonts/blackcry.ttf new file mode 100644 index 0000000..cca5091 Binary files /dev/null and b/demo/data/fonts/blackcry.ttf differ diff --git a/demo/src/SConstruct b/demo/src/SConstruct index b813931..2d51a2c 100644 --- a/demo/src/SConstruct +++ b/demo/src/SConstruct @@ -14,6 +14,7 @@ flags = ' -O0 -g -lm -Wall -fmessage-length=0 ' # files sources = [ + 'font.c', 'main.c', 'phisics.c', 'sprites.c' ] diff --git a/demo/src/font.c b/demo/src/font.c new file mode 100644 index 0000000..8c9691c --- /dev/null +++ b/demo/src/font.c @@ -0,0 +1,33 @@ + +#include + +#include + +#include "font.h" + + + +Font font; + + +void fontInit() { + font = createFont("data/fonts/blackcry.ttf"); +} + + +void fontDraw() { + double x = 512; + double y = 256; + + textSize(64*(1+sin(worldGetSeconds()/4))); + text("Here is the\nleft aligned\ntext. VAW.", x, y); + + textFont(font); + textAlign(HALIGN_RIGHT, VALIGN_TOP); + text("Here is the\nright aligned\ntext. VAW.", x, y); + + textFontDefault(); + textAlign(HALIGN_LEFT, VALIGN_TOP); +} + + diff --git a/demo/src/font.h b/demo/src/font.h new file mode 100644 index 0000000..9fc0e87 --- /dev/null +++ b/demo/src/font.h @@ -0,0 +1,10 @@ +#ifndef FONT_H +#define FONT_H + + +void fontInit(); +void fontDraw(); + + +#endif + diff --git a/demo/src/main.c b/demo/src/main.c index dd5ce42..4e00fe8 100644 --- a/demo/src/main.c +++ b/demo/src/main.c @@ -3,16 +3,19 @@ #include "phisics.h" #include "sprites.h" +#include "font.h" void init() { phisicsInit(); spritesInit(); + fontInit(); } void draw() { phisicsDraw(); spritesDraw(); + fontDraw(); drawSprites(); point(mouseX(), mouseY()); diff --git a/demo/src/sprites.c b/demo/src/sprites.c index 1657ac7..dab8bbd 100644 --- a/demo/src/sprites.c +++ b/demo/src/sprites.c @@ -102,8 +102,8 @@ void spritesDraw() { double time = worldGetSeconds(); for(int i = 0; i < groupGetCount(pulse); ++i) { - double scale = exp( scaleAmplitude * sin(shift + time/scalePeriod*2*PI) ); - double rotation = rotateAmplitude * sin(shift + time/rotatePeriod*2*PI); + double scale = exp( scaleAmplitude * sin(shift*i + time/scalePeriod*2*PI) ); + double rotation = rotateAmplitude * sin(shift*i + time/rotatePeriod*2*PI); Sprite s = groupGet(pulse, i); spriteSetScale(s, scale); diff --git a/src/font.c b/src/font.c index 24d5806..5b5a09c 100644 --- a/src/font.c +++ b/src/font.c @@ -98,9 +98,13 @@ static HeliFontMap* createFontMap() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -0.7f); + char *buffer = calloc(1, FONT_MAP_TEXSIZE*FONT_MAP_TEXSIZE); - for(int size = FONT_MAP_TEXSIZE, border = FONT_MAP_BORDERSIZE; border > 0; border <<= 1, size <<= 1) - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, size, size, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buffer); + int level = 0; + for(int size = FONT_MAP_TEXSIZE, border = FONT_MAP_BORDERSIZE; border > 0; border >>= 1, size >>= 1, ++level) + glTexImage2D(GL_TEXTURE_2D, level, GL_ALPHA, size, size, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buffer); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level - 1); free(buffer); glBindTexture(GL_TEXTURE_2D, 0); @@ -141,60 +145,62 @@ static HeliGlyph* loadGlyph(HeliFontInstance *fi, int code) { g->b = (-metrics->horiBearingY + metrics->height)*ftkf; g->advance = metrics->horiAdvance*ftkf; - FT_Matrix matrix = {}; - matrix.xx = (FONT_MAP_GLYPHWORKSIZE-2)*64*65536/metrics->width; - matrix.yy = (FONT_MAP_GLYPHWORKSIZE-2)*64*65536/metrics->height; - FT_Vector offset = {}; - offset.x = 64 - metrics->horiBearingX; - offset.y = 64 + metrics->horiBearingY - metrics->height; - FT_Set_Transform(fi->face, &matrix, &offset); - int success = !FT_Load_Glyph(fi->face, index, FT_LOAD_NO_HINTING) - && !FT_Render_Glyph(fi->face->glyph, FT_RENDER_MODE_NORMAL); - matrix.xx = matrix.yy = 65536; - FT_Set_Transform(fi->face, NULL, NULL); - if (!success) return &blankGlyph; - - const FT_Bitmap *bitmap = &fi->face->glyph->bitmap; - unsigned char buffer[FONT_MAP_GLYPHWORKSIZE * FONT_MAP_GLYPHWORKSIZE] = {}; - int dr = fi->face->glyph->bitmap_top + 1 - FONT_MAP_GLYPHWORKSIZE; - int dc = -fi->face->glyph->bitmap_left; - int r0 = -dr; - int r1 = r0 + bitmap->rows; - int c0 = -dc; - int c1 = c0 + bitmap->width; - if (r0 < 0) r0 = 0; - if (c0 < 0) c0 = 0; - if (r1 > FONT_MAP_GLYPHWORKSIZE) r1 = FONT_MAP_GLYPHWORKSIZE; - if (c1 > FONT_MAP_GLYPHWORKSIZE) c1 = FONT_MAP_GLYPHWORKSIZE; - for(int r = r0; r < r1; ++r) - for(int c = c0; c < c1; ++c) - buffer[r*FONT_MAP_GLYPHWORKSIZE + c] = *(bitmap->buffer + bitmap->pitch*(r + dr) + dc); + unsigned char buffer[FONT_MAP_GLYPHSIZE * FONT_MAP_GLYPHSIZE] = {}; + if (metrics->width > 0 && metrics->height > 0) { + FT_Matrix matrix = {}; + matrix.xx = (FONT_MAP_GLYPHWORKSIZE-2)*64*65536/metrics->width; + matrix.yy = (FONT_MAP_GLYPHWORKSIZE-2)*64*65536/metrics->height; + FT_Vector offset = {}; + offset.x = 64 - metrics->horiBearingX; + offset.y = -(64 + metrics->horiBearingY - metrics->height); + FT_Set_Transform(fi->face, &matrix, &offset); + int success = !FT_Load_Glyph(fi->face, index, FT_LOAD_NO_HINTING) + && !FT_Render_Glyph(fi->face->glyph, FT_RENDER_MODE_NORMAL); + matrix.xx = matrix.yy = 65536; + FT_Set_Transform(fi->face, NULL, NULL); + if (!success) return &blankGlyph; + + const FT_Bitmap *bitmap = &fi->face->glyph->bitmap; + int dr = fi->face->glyph->bitmap_top + 1 - FONT_MAP_GLYPHWORKSIZE; + int dc = -fi->face->glyph->bitmap_left; + int r0 = -dr; + int r1 = r0 + bitmap->rows; + int c0 = -dc; + int c1 = c0 + bitmap->width; + if (r0 < 0) r0 = 0; + if (c0 < 0) c0 = 0; + if (r1 > FONT_MAP_GLYPHWORKSIZE) r1 = FONT_MAP_GLYPHWORKSIZE; + if (c1 > FONT_MAP_GLYPHWORKSIZE) c1 = FONT_MAP_GLYPHWORKSIZE; + for(int r = r0; r < r1; ++r) + for(int c = c0; c < c1; ++c) + buffer[r*FONT_MAP_GLYPHSIZE + c] = *(bitmap->buffer + bitmap->pitch*(r + dr) + c + dc); + } glBindTexture(GL_TEXTURE_2D, g->map->texid); int gi = g - g->map->glyphs; int r = gi/FONT_MAP_CNT; int c = gi%FONT_MAP_CNT; - int size = FONT_MAP_GLYPHWORKSIZE; - for(int level = 0, border = FONT_MAP_BORDERSIZE; border > 0; border <<= 1, ++level) { + int size = FONT_MAP_GLYPHSIZE; + for(int level = 0, border = FONT_MAP_BORDERSIZE; border > 0; border >>= 1, ++level) { glTexSubImage2D( GL_TEXTURE_2D, level, - c*(size + border), - r*(size + border), + c*size, + r*size, size, size, GL_ALPHA, GL_UNSIGNED_BYTE, buffer ); - size <<= 1; if (border > 1) { + size >>= 1; for(int r = 0; r < size; ++r) for(int c = 0; c < size; ++c) buffer[r*size + c] = (unsigned char)(( - (int)buffer[(r+0)*2*size + (c+0)*2] - + (int)buffer[(r+0)*2*size + (c+1)*2] - + (int)buffer[(r+1)*2*size + (c+0)*2] - + (int)buffer[(r+1)*2*size + (c+1)*2] + 2) << 2); + (unsigned int)buffer[((r*2 + 0)*size + c)*2 + 0] + + (unsigned int)buffer[((r*2 + 0)*size + c)*2 + 1] + + (unsigned int)buffer[((r*2 + 1)*size + c)*2 + 0] + + (unsigned int)buffer[((r*2 + 1)*size + c)*2 + 1] + 2) >> 2 ); } } glBindTexture(GL_TEXTURE_2D, 0); @@ -202,6 +208,7 @@ static HeliGlyph* loadGlyph(HeliFontInstance *fi, int code) { g->fi = fi; g->code = code; g->index = index; + ++g->map->count; return g; } @@ -235,7 +242,7 @@ static HeliFontInstance* loadFont(const char *path) { args.flags = FT_OPEN_MEMORY; args.memory_base = (FT_Byte*)heliBlobDefaultFont; args.memory_size = heliBlobDefaultFontSize; - if (!FT_Open_Face(ftLibrary, &args, 0, &fi->face)) { + if (FT_Open_Face(ftLibrary, &args, 0, &fi->face)) { printf("Cannot initialize default font"); fi->face = NULL; } @@ -389,9 +396,9 @@ void text(const char *text, double x, double y) { FT_KERNING_UNFITTED, &kerning )) cc->pos += kerning.x/64.0; - if (line->l > cc->glyph->l) line->l = cc->glyph->l; + if (line->l > cc->glyph->l + cc->pos) line->l = cc->glyph->l + cc->pos; + if (line->r < cc->glyph->r + cc->pos) line->r = cc->glyph->r + cc->pos; if (line->t > cc->glyph->t) line->t = cc->glyph->t; - if (line->r < cc->glyph->r) line->r = cc->glyph->r; if (line->b < cc->glyph->b) line->b = cc->glyph->b; } } @@ -429,7 +436,7 @@ void text(const char *text, double x, double y) { // sort by textures int charsCount = lines[linesCount-1].end; - for(int i = 0; i < charsCount; ++i) + for(int i = 0; i < charsCount-1; ++i) chars[i].next = &chars[i+1]; HeliCharDesc *first = NULL, *last = NULL, *current = chars; while(current) { @@ -471,14 +478,15 @@ void text(const char *text, double x, double y) { } double dx = (cc->glyph->r - cc->glyph->l)*borderK; - double dy = (cc->glyph->t - cc->glyph->b)*borderK; + double dy = (cc->glyph->b - cc->glyph->t)*borderK; double l = cc->x + cc->glyph->l - dx; double t = cc->y + cc->glyph->t - dy; double r = cc->x + cc->glyph->r + dx; double b = cc->y + cc->glyph->b + dy; - double tl = (cc->glyph->index % FONT_MAP_CNT)*texStep + texOffset; - double tt = (cc->glyph->index / FONT_MAP_CNT)*texStep + texOffset; + int gi = cc->glyph - cc->glyph->map->glyphs; + double tl = (gi % FONT_MAP_CNT)*texStep + texOffset; + double tt = (gi / FONT_MAP_CNT)*texStep + texOffset; double tr = tl + texStep; double tb = tt + texStep; diff --git a/src/helianthus.h b/src/helianthus.h index 9990ca7..0640a6f 100644 --- a/src/helianthus.h +++ b/src/helianthus.h @@ -7,6 +7,7 @@ #include "helianthus/sprite.h" #include "helianthus/group.h" #include "helianthus/drawing.h" +#include "helianthus/font.h" #endif diff --git a/src/world.c b/src/world.c index c9a5743..b7e63f2 100644 --- a/src/world.c +++ b/src/world.c @@ -256,7 +256,7 @@ static int init() { SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);