Skip to content

Commit

Permalink
Fix zeros and add build files.
Browse files Browse the repository at this point in the history
Arabic and Persian zero turned into an elevated dot.

Other additions:
- Makefile watch and ttftest rules
- build script for watching using inodewatch
- README updates
- Update the glyphs picture
  • Loading branch information
mehdisadeghi committed Apr 7, 2022
1 parent 6f266fc commit 161d571
Show file tree
Hide file tree
Showing 6 changed files with 243 additions and 32 deletions.
15 changes: 13 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
.PHONY: clean all
.PHONY: clean all watch

all: noqte.ttf

noqte.ttf: noqte.sfd
fontforge -quiet -lang ff -c "Open(\"noqte.sfd\",1);Generate(\"noqte.ttf\")"

ttftest: *.c
gcc *.c \
-I/usr/include/SDL2 -lSDL2 -lSDL2_ttf \
-I/usr/include/harfbuzz -I/usr/include/freetype2 \
-I/usr/include/glib-2.0 \
-I/usr/lib/glib-2.0/include \
-o ttftest

watch:
./build.sh noqte.sfd ttftest.c

clean:
rm noqte.ttf
rm -f noqte.ttf ttftest
26 changes: 20 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# Noqte
A fun, minimalistic Persian pixel font - WIP.
A fun, minimalistic Persian pixel font.
![](noqte.png)

## Introduction
I made this font in a week from scratch in order to use it in my game. The em-height is 1024 points. Each glyph is made of 64x64 points squares. There are some exceptions, sadly, mainly for designing diacritics. Those might be removed in a final version, however. For those at moment another square size is used which is 75% smaller, i.e. 32x32 points.
I made this font in a week from scratch in order to use it in my game. The em-height is 1024 points. Each glyph is made of 100x100 points squares. There are some exceptions, sadly, mainly for designing diacritics. Those might be removed in a final version, however. For those at moment another square size is used which is 75% of the base square, i.e. 75x75 points.

I have made a few design choices and tried to remain consistent as much as possible:
- There is no left bearing anywhere
- All initial glyphs have one block right bearing (64 points empty space to the right)
- All initial glyphs have one block right bearing (100 points empty space to the right)
- Important: medial forms have no bearing to the right. I assumed that other initial or medial glyph should consider this and add blocks to the left if necessary
- The bottom left block on each initial glyph is empty
- The bottom left block on each initial glyph is empty (exceptions FEH & QAF)
- The bottom left block on each medial glyph is full

There might be some minor divergences, which is either a bug and should be fixed or is due to diacritics.
Expand All @@ -19,7 +19,10 @@ The font covers main charachters for Persian from the following Unicode blocks:
- Arabic (0600–06FF)
- Arabic Presentation Forms-A (FB50–FDFF)
- Arabic Presentation Forms-B (FE70–FEFF)
- Basic Latin (ASCII) - letters missing
- Basic Latin (ASCII)
- Latin-1 Supplement (partial)

Moreover, Basic Latin i.e. ASCII and some suplementary letters and signs are included. I included as much as necessary to make the font usable for German and Spanish.

## Glyphs
Here is a subset of glyphs.
Expand All @@ -40,6 +43,17 @@ Please report them on the repository or email me. The following problems are kno
- There are no anchors
- Diacritics are not well-positioned

## Test
There is a development script and an SDL test file included. To watch the changes and rebuild do:

$ make watch

or directly

$ make ttftest

and then run `ttftest` executable. SDL and HarfBuzz should be available on your system.

## Aknowledgement
Credit when credit is due. I benefited from the work of others mentioned below.

Expand All @@ -52,4 +66,4 @@ Credit when credit is due. I benefited from the work of others mentioned below.

# License
Noqte is released under the [OFL license](LICENSE).
Copyright (C) 2022 Mehdi Sadeghi
Copyright (C) 2022 Mehdi Sadeghi
18 changes: 18 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash

if [ "$#" -lt 2 ]; then
echo 'Usage: build.sh <FILE> [ ... ]'
fi

PID=
while inotifywait -e CLOSE_WRITE $@; do
test "$PID" && kill -9 "$PID"
cp -r $1 backup/$(date --iso-8601=seconds)_$1
fontforge -quiet -lang ff -c "Open(\"$1\",1);Generate(\"noqte.ttf\")"
echo Starting...
make noqte.ttf ttftest
./ttftest &
PID=$!
echo PID=$PID
sleep 3
done
Binary file modified glyphs.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 13 additions & 24 deletions noqte.sfd
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ OS2Version: 4
OS2_WeightWidthSlopeOnly: 0
OS2_UseTypoMetrics: 1
CreationTime: 1581968550
ModificationTime: 1649368391
ModificationTime: 1649371633
PfmFamily: 33
TTFWeight: 500
TTFWidth: 5
Expand Down Expand Up @@ -739,7 +739,7 @@ DisplaySize: -48
AntiAlias: 1
FitToEm: 1
WidthSeparation: 154
WinInfo: 0 26 19
WinInfo: 0 25 19
BeginPrivate: 0
EndPrivate
Grid
Expand Down Expand Up @@ -1689,25 +1689,22 @@ EndChar

StartChar: uni06F0
Encoding: 1776 1776 60
Width: 400
Width: 200
VWidth: 803
GlyphClass: 1
UnlinkRmOvrlpSave: 1
Flags: W
LayerCount: 2
Fore
Refer: 207 -1 N 1 0 0 1 100 0 2
Refer: 207 -1 N 1 0 0 1 200 100 2
Refer: 207 -1 N 1 0 0 1 0 100 2
Refer: 207 -1 N 1 0 0 1 100 200 2
Refer: 207 -1 S 1 0 0 1 0 100 2
EndChar

StartChar: uni06F1
Encoding: 1777 1777 61
Width: 200
VWidth: 803
GlyphClass: 1
Flags: W
Flags: WO
LayerCount: 2
Fore
Refer: 207 -1 S 1 0 0 1 0 400 2
Expand Down Expand Up @@ -1736,21 +1733,16 @@ EndChar

StartChar: uni06F3
Encoding: 1779 1779 63
Width: 600
Width: 500
VWidth: 803
GlyphClass: 1
Flags: W
LayerCount: 2
Fore
Refer: 207 -1 N 1 0 0 1 0 400 2
Refer: 207 -1 N 1 0 0 1 0 300 2
Refer: 207 -1 N 1 0 0 1 0 200 2
Refer: 207 -1 N 1 0 0 1 0 100 2
Refer: 207 -1 N 1 0 0 1 0 0 2
Refer: 207 -1 N 1 0 0 1 400 400 2
Refer: 207 -1 N 1 0 0 1 300 300 2
Refer: 207 -1 N 1 0 0 1 200 400 2
Refer: 207 -1 N 1 0 0 1 100 300 2
Refer: 207 -1 N 1 0 0 1 300 400 2
Refer: 207 -1 S 1 0 0 1 200 300 2
Refer: 207 -1 N 1 0 0 1 100 400 2
Refer: 61 1777 N 1 0 0 1 0 0 2
EndChar

StartChar: uni06F4
Expand Down Expand Up @@ -1870,7 +1862,7 @@ Encoding: 64342 64342 70
Width: 800
VWidth: 803
GlyphClass: 1
Flags: WO
Flags: W
LayerCount: 2
Fore
Refer: 52 1662 N 1 0 0 1 0 0 2
Expand Down Expand Up @@ -3680,15 +3672,12 @@ EndChar

StartChar: uni0660
Encoding: 1632 1632 212
Width: 300
Width: 200
VWidth: 803
Flags: MW
LayerCount: 2
Fore
Refer: 207 -1 N 1 0 0 1 0 0 2
Refer: 207 -1 N 1 0 0 1 100 0 2
Refer: 207 -1 N 1 0 0 1 100 100 2
Refer: 207 -1 N 1 0 0 1 0 100 2
Refer: 60 1776 N 1 0 0 1 0 0 2
EndChar

StartChar: uni0661
Expand Down
179 changes: 179 additions & 0 deletions ttftest.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
#include <SDL.h>
#include <SDL_ttf.h>
#include <hb.h>

void blit(SDL_Texture *texture, int x, int y, int rtl);
SDL_Texture *loadTXTTexture(char *text, TTF_Font *font, int rtl);

static TTF_Font *noqte;
static TTF_Font *dejavu;
static TTF_Font *noto;
static TTF_Font *console;
static TTF_Font *consolereg;
static SDL_Window *window;
static SDL_Renderer *renderer;

int main(int argc, char ** argv)
{
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("Couldn't initialize SDL: %s\n", SDL_GetError());
exit(1);
}

if (TTF_Init() < 0)
{
printf("Couldn't initialize SDL_ttf");
exit(1);
}

int major, minor, patch;
TTF_GetHarfBuzzVersion(&major, &minor, &patch);
if (!(major || minor || patch))
{
printf("SDL_ttf compiled without HarfBuz support");
exit(1);
}

noqte = TTF_OpenFont("noqte.ttf", 50);
if (noqte == NULL)
{
printf("Couldn't load the font");
exit(1);
}

window = SDL_CreateWindow("ttftest",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
1280, 720,
SDL_WINDOW_RESIZABLE);
if (!window)
{
printf("Failed to open window: %s\n", SDL_GetError());
exit(1);
}

SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");

renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (!renderer)
{
printf("Failed to create renderer: %s\n", SDL_GetError());
exit(1);
}

SDL_Texture *t01 = loadTXTTexture("ء ا آ ب پ ت ث ج چ ح خ د ذ ر ز ژ س ش", noqte, 1);
SDL_Texture *t02 = loadTXTTexture("ص ض ط ظ ع غ ف ق ک گ ل م ن و ه ی ", noqte, 1);
SDL_Texture *t03 = loadTXTTexture(
"۱۲°۳۴۵۶۷۸۹۰!"
"÷ ! ٬ ٫ ٪ ﷼ × ، * ) ( ـ + - = "
, noqte, 1);
SDL_Texture *t04 = loadTXTTexture(
//"ْ ٌ ٍ ً ُ ِ َ ّ ٓ ٔ "
"ْ ٌ ٍ ً ُ ِ َ ّ ] [ } { » « : ;"
" > < ؟ < . /"
, noqte, 1);
SDL_Texture *t05 = loadTXTTexture(
"در صورت حذف این چند واژه غلط به شکیل، ثابت و جامع‌تر ساختن ",
noqte, 1);
SDL_Texture *t06 = loadTXTTexture(
"پاراگراف شعر از لحاظ دوری از قافیه‌های اضافه کمک می‌شود.",
noqte, 1);
SDL_Texture *t07 = loadTXTTexture("äüößabcdefghijklmnñopqrstuvwxyz", noqte, 0);
SDL_Texture *t08 = loadTXTTexture("ÄÜÖABCDEFGHIJKLMNÑOPQRSTUVWXYZ", noqte, 0);
SDL_Texture *t09 = loadTXTTexture("0123456789°!\"§$%&/()=?`" , noqte, 0);

SDL_Texture *t10 = loadTXTTexture("The quick brown fox jumps over the lazy dog", noqte, 0);
SDL_Texture *t11 = loadTXTTexture("THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG", noqte, 0);
SDL_Texture *t12 = loadTXTTexture("el veloz murciélago hindú comía feliz cardillo y kiwi.", noqte, 0);
SDL_Texture *t13 = loadTXTTexture("la cigüeña tocaba el saxofón detrás del palenque de paja", noqte, 0);


SDL_Event event;

while (1)
{
SDL_RenderClear(renderer);

while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
exit(0);
break;

default:
break;
}
}

int right = 1075;

blit(t01, right, 25, 1);
blit(t02, right, 100, 1);
blit(t03, right, 175, 1);
blit(t04, right, 250, 1);

blit(t05, right, 325, 1);
blit(t06, right, 400, 1);

blit(t07, 10, 475, 0);
blit(t08, 10, 550, 0);

blit(t09, 10, 625, 0);
blit(t10, 10, 700, 0);
blit(t11, 10, 775, 0);
blit(t12, 10, 850, 0);

SDL_Delay(32);
SDL_RenderPresent(renderer);
}

SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
TTF_CloseFont(noqte);
TTF_Quit();
SDL_Quit();
}

SDL_Texture *loadTXTTexture(char *text, TTF_Font *font, int rtl)
{
SDL_Rect dest;

SDL_Color colorA = { 0xff, 0x99, 0x00, 0xff };

if (rtl)
{
TTF_SetDirection(HB_DIRECTION_RTL);
TTF_SetScript(HB_SCRIPT_ARABIC);
} else {
TTF_SetDirection(HB_DIRECTION_LTR);
TTF_SetScript(HB_SCRIPT_LATIN);
}

SDL_Surface *surface;

surface = TTF_RenderUTF8_Blended(font, text, colorA);

SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer, surface);

SDL_FreeSurface(surface);

return texture;
}

void blit(SDL_Texture *texture, int x, int y, int rtl)
{
SDL_Rect dest;

dest.x = x;
dest.y = y;

SDL_QueryTexture(texture, NULL, NULL, &dest.w, &dest.h);

if (rtl)
dest.x -= dest.w;

SDL_RenderCopy(renderer, texture, NULL, &dest);
}

0 comments on commit 161d571

Please # to comment.