URI: 
       tMove unused files to unused/ - ltkx - GUI toolkit for X11 (WIP)
  HTML git clone git://lumidify.org/ltkx.git
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit ba0e522da0cb698021de15f24971b8c661d3941f
   DIR parent 7b5498e387d5d8d05ffaf404e665a32f2de32e75
  HTML Author: lumidify <nobody@lumidify.org>
       Date:   Thu, 21 May 2020 18:01:08 +0200
       
       Move unused files to unused/
       
       Diffstat:
         M Makefile                            |       2 +-
         M button.c                            |       2 +-
         M ltk.c                               |       5 +++--
         M ltkx.h                              |       2 +-
         D temp                                |       1 -
         M test1.c                             |       2 +-
         D text-common.c                       |     410 ------------------------------
         M text_buffer.c                       |       2 +-
         M text_buffer.h                       |       2 +-
         A text_common.c                       |     410 ++++++++++++++++++++++++++++++
         R text-common.h -> text_common.h      |       0 
         M text_edit.c                         |       2 +-
         D tmpfb.txt                           |      67 -------------------------------
         D tmpnofb.txt                         |      63 -------------------------------
         R Lumidify_Casual.ttf -> unused/Lumi… |       0 
         R gap_buffer.h -> unused/gap_buffer.h |       0 
         R main.c -> unused/main.c             |       0 
         R stack.h -> unused/stack.h           |       0 
         R text-hb.c -> unused/text-hb.c       |       0 
         R text-hb.h -> unused/text-hb.h       |       0 
         R text.c -> unused/text.c             |       0 
         R text.c.bak -> unused/text.c.bak     |       0 
         R text.h -> unused/text.h             |       0 
         R text/Awami_beta3.ttf -> unused/tex… |       0 
         R text/FONTLOG.txt -> unused/text/FO… |       0 
         R text/GENTIUM-FAQ.txt -> unused/tex… |       0 
         R text/GentiumPlus-I.ttf -> unused/t… |       0 
         R text/GentiumPlus-R.ttf -> unused/t… |       0 
         R text/LICENSE_OFL.txt -> unused/tex… |       0 
         R text/Makefile -> unused/text/Makef… |       0 
         R text/NotoNastaliqUrdu-Regular.ttf … |       0 
         R text/OFL-FAQ.txt -> unused/text/OF… |       0 
         R text/OFL.txt -> unused/text/OFL.txt |       0 
         R text/README -> unused/text/README   |       0 
         R text/README.txt -> unused/text/REA… |       0 
         R text/bob.c -> unused/text/bob.c     |       0 
         R text/font.ttf -> unused/text/font.… |       0 
         R text/font1.ttf -> unused/text/font… |       0 
         R text/font2.ttf -> unused/text/font… |       0 
         R text/hashtest.c -> unused/text/has… |       0 
         R text/khash.h -> unused/text/khash.h |       0 
         R text/main.c -> unused/text/main.c   |       0 
         R text/main1.c -> unused/text/main1.c |       0 
         R text/new.c -> unused/text/new.c     |       0 
         R text/stb_image_write.h -> unused/t… |       0 
         R text/stb_truetype.h -> unused/text… |       0 
         R text/test.c -> unused/text/test.c   |       0 
         R text/test23.c -> unused/text/test2… |       0 
         R text/test3.c -> unused/text/test3.c |       0 
         R text/text-hb.c -> unused/text/text… |       0 
         R text/text-hb.new.c -> unused/text/… |       0 
         R text/text-hb.ubernew.c -> unused/t… |       0 
         R text/text-hb.uberubernew.c -> unus… |       0 
         R text/text.c -> unused/text/text.c   |       0 
         R text/text1.c -> unused/text/text1.c |       0 
         R text/text2.c -> unused/text/text2.c |       0 
         R text/tmp.c -> unused/text/tmp.c     |       0 
         R text/utf8.c -> unused/text/utf8.c   |       0 
         R text/utf8.h -> unused/text/utf8.h   |       0 
         R text/utf8_new.c -> unused/text/utf… |       0 
         R theme.c -> unused/theme.c           |       0 
         R theme.h -> unused/theme.h           |       0 
       
       62 files changed, 420 insertions(+), 550 deletions(-)
       ---
   DIR diff --git a/Makefile b/Makefile
       t@@ -1,7 +1,7 @@
        LIBS = -lm `pkg-config --libs x11 harfbuzz fontconfig fribidi`
        STD = -std=c99
        CFLAGS = -g -w -fcommon -Wall -Werror -Wextra `pkg-config --cflags x11 harfbuzz fontconfig fribidi` -pedantic
       -OBJ = stb_truetype.o text_edit.o text-common.o text_buffer.o ltk.o ini.o grid.o button.o test1.o
       +OBJ = stb_truetype.o text_edit.o text_common.o text_buffer.o ltk.o ini.o grid.o button.o test1.o
        
        test1: $(OBJ)
                gcc $(STD) -o $@ $(OBJ) $(LIBS)
   DIR diff --git a/button.c b/button.c
       t@@ -31,7 +31,7 @@
        #include <fribidi.h>
        #include <harfbuzz/hb.h>
        #include <fontconfig/fontconfig.h>
       -#include "text-common.h"
       +#include "text_common.h"
        #include "array.h"
        #include "text_buffer.h"
        #include "button.h"
   DIR diff --git a/ltk.c b/ltk.c
       t@@ -32,8 +32,9 @@
        #include <fribidi.h>
        #include <harfbuzz/hb.h>
        #include <fontconfig/fontconfig.h>
       -#include "text-common.h"
       -#include "text-hb.h"
       +#include "array.h"
       +#include "text_common.h"
       +#include "text_buffer.h"
        
        Ltk *ltk_global;
        
   DIR diff --git a/ltkx.h b/ltkx.h
       t@@ -8,7 +8,7 @@
        #include <fribidi.h>
        #include <harfbuzz/hb.h>
        #include <harfbuzz/hb-ot.h>
       -#include "text-common.h"
       +#include "text_common.h"
        #include "button.h"
        #include "grid.h"
        #include "array.h"
   DIR diff --git a/temp b/temp
       t@@ -1 +0,0 @@
       -https://tronche.com/gui/x/xlib/window-information/XGetGeometry.html
   DIR diff --git a/test1.c b/test1.c
       t@@ -42,6 +42,6 @@ int main(int argc, char *argv[])
                LtkTextEdit *edit = ltk_create_text_edit(window1, "ہمارے بارے میں blabla bla");
                LtkButton *button4 = ltk_create_button(window1, "ہمارے بارے میں blablabla", &bob3, edit);
                ltk_grid_widget(button4, grid1, 1, 0, 1, 1, LTK_STICKY_TOP | LTK_STICKY_BOTTOM | LTK_STICKY_RIGHT);
       -        ltk_grid_widget(edit, grid1, 1, 1, 1, 1, LTK_STICKY_LEFT | LTK_STICKY_TOP | LTK_STICKY_RIGHT);
       +        ltk_grid_widget(edit, grid1, 1, 1, 1, 1, LTK_STICKY_LEFT | LTK_STICKY_BOTTOM | LTK_STICKY_TOP | LTK_STICKY_RIGHT);
                ltk_mainloop();
        }
   DIR diff --git a/text-common.c b/text-common.c
       t@@ -1,410 +0,0 @@
       -/*
       - * This file is part of the Lumidify ToolKit (LTK)
       - * Copyright (c) 2017, 2018, 2020 lumidify <nobody@lumidify.org>
       - *
       - * Permission is hereby granted, free of charge, to any person obtaining a copy
       - * of this software and associated documentation files (the "Software"), to deal
       - * in the Software without restriction, including without limitation the rights
       - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       - * copies of the Software, and to permit persons to whom the Software is
       - * furnished to do so, subject to the following conditions:
       - *
       - * The above copyright notice and this permission notice shall be included in all
       - * copies or substantial portions of the Software.
       - *
       - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
       - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
       - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
       - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
       - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
       - * SOFTWARE.
       - */
       -
       -#include <stdio.h>
       -#include <stdlib.h>
       -#include <stdint.h>
       -#include <limits.h>
       -#include <X11/Xlib.h>
       -#include <X11/Xutil.h>
       -#include "stb_truetype.h" /* http://nothings.org/stb/stb_truetype.h */
       -#include <fontconfig/fontconfig.h>
       -#include "khash.h"
       -#include <fribidi.h>
       -#include <harfbuzz/hb.h>
       -#include <harfbuzz/hb-ot.h>
       -#include "text-common.h"
       -#include "ltk.h"
       -
       -extern Ltk *ltk_global;
       -
       -/* These unicode routines are taken from
       - * https://github.com/JeffBezanson/cutef8 */
       -
       -/* is c the start of a utf8 sequence? */
       -#define isutf(c) (((c)&0xC0)!=0x80)
       -
       -static const uint32_t offsetsFromUTF8[6] = {
       -    0x00000000UL, 0x00003080UL, 0x000E2080UL,
       -    0x03C82080UL, 0xFA082080UL, 0x82082080UL
       -};
       -
       -/* next character without NUL character terminator */
       -uint32_t u8_nextmemchar(const char *s, size_t *i)
       -{
       -    uint32_t ch = 0;
       -    size_t sz = 0;
       -    do {
       -        ch <<= 6;
       -        ch += (unsigned char)s[(*i)++];
       -        sz++;
       -    } while (!isutf(s[*i]));
       -    ch -= offsetsFromUTF8[sz-1];
       -
       -    return ch;
       -}
       -
       -/* number of characters in NUL-terminated string */
       -size_t u8_strlen(const char *s)
       -{
       -    size_t count = 0;
       -    size_t i = 0, lasti;
       -
       -    while (1) {
       -        lasti = i;
       -        while (s[i] > 0)
       -            i++;
       -        count += (i-lasti);
       -        if (s[i++]==0) break;
       -        (void)(isutf(s[++i]) || isutf(s[++i]) || ++i);
       -        count++;
       -    }
       -    return count;
       -}
       -
       -size_t u8_wc_toutf8(char *dest, uint32_t ch)
       -{
       -    if (ch < 0x80) {
       -        dest[0] = (char)ch;
       -        return 1;
       -    }
       -    if (ch < 0x800) {
       -        dest[0] = (ch>>6) | 0xC0;
       -        dest[1] = (ch & 0x3F) | 0x80;
       -        return 2;
       -    }
       -    if (ch < 0x10000) {
       -        dest[0] = (ch>>12) | 0xE0;
       -        dest[1] = ((ch>>6) & 0x3F) | 0x80;
       -        dest[2] = (ch & 0x3F) | 0x80;
       -        return 3;
       -    }
       -    if (ch < 0x110000) {
       -        dest[0] = (ch>>18) | 0xF0;
       -        dest[1] = ((ch>>12) & 0x3F) | 0x80;
       -        dest[2] = ((ch>>6) & 0x3F) | 0x80;
       -        dest[3] = (ch & 0x3F) | 0x80;
       -        return 4;
       -    }
       -    return 0;
       -}
       -
       -LtkTextManager *
       -ltk_init_text(char *font_name)
       -{
       -        LtkTextManager *tm = malloc(sizeof(LtkTextManager));
       -        if (!tm) {
       -                (void)printf("Memory exhausted when trying to create text manager.");
       -                exit(1);
       -        }
       -        tm->font_paths = kh_init(fontid);
       -        tm->font_cache = kh_init(fontstruct);
       -        tm->glyph_cache = kh_init(glyphcache);
       -        /* FIXME: THIS REALLY SHOULD NOT BE UINT16_T! IT GETS MESSY WITH BIT-SHIFTING */
       -        tm->font_id_cur = 1;
       -        ltk_load_default_font(tm, font_name);
       -
       -        return tm;
       -}
       -
       -void
       -ltk_destroy_text_manager(LtkTextManager *tm)
       -{
       -        int k;
       -
       -        kh_destroy(fontid, tm->font_paths);
       -
       -        for (k = kh_begin(tm->font_cache); k != kh_end(tm->font_cache); k++) {
       -                if (kh_exist(tm->font_cache, k)) {
       -                        ltk_destroy_font(kh_value(tm->font_cache, k));
       -                }
       -        }
       -        kh_destroy(fontstruct, tm->font_cache);
       -
       -        for (k = kh_begin(tm->glyph_cache); k != kh_end(tm->glyph_cache); k++) {
       -                if (kh_exist(tm->glyph_cache, k)) {
       -                        ltk_destroy_glyph_cache(kh_value(tm->glyph_cache, k));
       -                }
       -        }
       -        kh_destroy(glyphcache, tm->glyph_cache);
       -
       -        free(tm);
       -}
       -
       -LtkGlyphInfo *
       -ltk_create_glyph_info(LtkFont *font, unsigned int id, float scale)
       -{
       -        LtkGlyphInfo *glyph = malloc(sizeof(LtkGlyphInfo));
       -        if (!glyph) {
       -                (void)printf("Out of memory!\n");
       -                exit(1);
       -        }
       -
       -        glyph->id = id;
       -        glyph->refs = 0;
       -        glyph->alphamap = stbtt_GetGlyphBitmap(
       -                &font->info, scale, scale, id, &glyph->w,
       -                &glyph->h, &glyph->xoff, &glyph->yoff
       -        );
       -
       -        return glyph;
       -}
       -
       -void
       -ltk_destroy_glyph_info(LtkGlyphInfo *gi)
       -{
       -        free(gi->alphamap);
       -        free(gi);
       -}
       -
       -LtkGlyphInfo *
       -ltk_get_glyph_info(LtkFont *font, unsigned int id, float scale, khash_t(glyphinfo) *cache)
       -{
       -        int ret;
       -        khint_t k;
       -        LtkGlyphInfo *glyph;
       -        k = kh_get(glyphinfo, cache, id);
       -        if (k == kh_end(cache)) {
       -                glyph = ltk_create_glyph_info(font, id, scale);
       -                /* FIXME: error checking with ret */
       -                k = kh_put(glyphinfo, cache, id, &ret);
       -                kh_value(cache, k) = glyph;
       -        } else {
       -                glyph = kh_value(cache, k);
       -        }
       -
       -        return glyph;
       -}
       -
       -khint_t
       -ltk_create_glyph_cache(LtkTextManager *tm, uint16_t font_id, uint16_t font_size)
       -{
       -        khash_t(glyphinfo) *cache = kh_init(glyphinfo);
       -        int ret;
       -        khint_t k;
       -        /* I guess I can just ignore ret for now */
       -        k = kh_put(glyphcache, tm->glyph_cache, font_id << 16 + font_size, &ret);
       -        kh_value(tm->glyph_cache, k) = cache;
       -
       -        return k;
       -}
       -
       -void
       -ltk_destroy_glyph_cache(khash_t(glyphinfo) *cache)
       -{
       -        int k;
       -        for (k = kh_begin(cache); k != kh_end(cache); k++) {
       -                if (kh_exist(cache, k)) {
       -                        ltk_destroy_glyph_info(kh_value(cache, k));
       -                }
       -        }
       -        kh_destroy(glyphinfo, cache);
       -}
       -
       -void
       -ltk_load_default_font(LtkTextManager *tm, char *name)
       -{
       -        FcPattern *match;
       -        FcResult result;
       -        char *file;
       -        int index;
       -        uint16_t font;
       -
       -        tm->fcpattern = FcNameParse(name);
       -        FcPatternAddString(tm->fcpattern, FC_FONTFORMAT, "truetype");
       -        FcConfigSubstitute(NULL, tm->fcpattern, FcMatchPattern);
       -        FcDefaultSubstitute(tm->fcpattern);
       -        match = FcFontMatch(NULL, tm->fcpattern, &result);
       -
       -        FcPatternGetString (match, FC_FILE, 0, (FcChar8 **) &file);
       -        /* FIXME: Why is index never used? This is the index within the font file,
       -           so it might be important, although I'm not sure if stb_truetype even
       -           supports it */
       -        FcPatternGetInteger (match, FC_INDEX, 0, &index);
       -
       -        tm->default_font = ltk_get_font(tm, file);
       -
       -        FcPatternDestroy (match);
       -}
       -
       -LtkFont *
       -ltk_create_font(char *path, uint16_t id)
       -{
       -        long len;
       -        LtkFont *font = malloc(sizeof(LtkFont));
       -        if (!font) {
       -                (void)fprintf(stderr, "Out of memory!\n");
       -                exit(1);
       -        }
       -        char *contents = ltk_read_file(path, &len);
       -        if (!stbtt_InitFont(&font->info, contents, 0))
       -        {
       -                (void)fprintf(stderr, "Failed to load font %s\n", path);
       -                exit(1);
       -        }
       -        /* FIXME: make use of the destroy function (last argument to hb_blob_create - see hb-blob.cc in harfbuzz source) */
       -        hb_blob_t *blob = hb_blob_create(contents, len, HB_MEMORY_MODE_READONLY, NULL, NULL);
       -        hb_face_t *face = hb_face_create(blob, 0);
       -        /* FIXME: need to use destroy function in order for the original file data to be freed? */
       -        hb_blob_destroy(blob);
       -        font->hb = hb_font_create(face);
       -        hb_face_destroy(face);
       -        hb_ot_font_set_funcs(font->hb);
       -        font->id = id;
       -        font->refs = 0;
       -
       -        return font;
       -}
       -
       -void
       -ltk_destroy_font(LtkFont *font)
       -{
       -        free(font->info.data);
       -        hb_font_destroy(font->hb);
       -        free(font);
       -}
       -
       -uint16_t
       -ltk_load_font(LtkTextManager *tm, char *path)
       -{
       -        LtkFont *font = ltk_create_font(path, tm->font_id_cur++);
       -        int ret;
       -        khint_t k;
       -        /* FIXME: does kh_destroy also free these copied strings properly? */
       -        char *key = strdup(path);
       -        k = kh_put(fontid, tm->font_paths, key, &ret);
       -        kh_value(tm->font_paths, k) = font->id;
       -        k = kh_put(fontstruct, tm->font_cache, (khint_t) font->id, &ret);
       -        kh_value(tm->font_cache, k) = font;
       -        k = kh_get(fontid, tm->font_paths, path);
       -
       -        return font->id;
       -}
       -
       -uint16_t
       -ltk_get_font(LtkTextManager *tm, char *path)
       -{
       -        int ret;
       -        khint_t k;
       -        uint16_t id;
       -        k = kh_get(fontid, tm->font_paths, path);
       -        if (k == kh_end(tm->font_paths)) {
       -                id = ltk_load_font(tm, path);
       -        } else {
       -                id = kh_value(tm->font_paths, k);
       -        }
       -
       -        return id;
       -}
       -
       -void
       -ltk_destroy_glyph(LtkGlyph *glyph, khash_t(glyphinfo) *cache)
       -{
       -        int k;
       -        if (--glyph->info->refs < 1) {
       -                k = kh_get(glyphinfo, cache, glyph->info->id);
       -                kh_del(glyphinfo, cache, k);
       -                ltk_destroy_glyph_info(glyph->info);
       -        }
       -        free(glyph);
       -}
       -
       -#if 0
       -/* based on http://codemadness.org/git/dwm-font/file/drw.c.html#l315 */
       -XImage *
       -ltk_render_text_line(
       -        LtkTextLine *tl,
       -        Display *dpy,
       -        Window window,
       -        GC gc,
       -        Colormap colormap,
       -        XColor fg,
       -        XColor bg)
       -{
       -        XWindowAttributes attrs;
       -        XGetWindowAttributes(dpy, window, &attrs);
       -        int depth = attrs.depth;
       -        XImage *img = XCreateImage(dpy, CopyFromParent, depth, ZPixmap, 0, NULL, tl->w, tl->h, 32, 0);
       -        img->data = calloc(img->bytes_per_line, img->height);
       -        XInitImage(img);
       -        int b;
       -        for (int i = 0; i < tl->h; i++) {
       -                b = img->bytes_per_line * i;
       -                for (int j = 0; j < tl->w; j++) {
       -                        img->data[b++] = bg.blue / 257;
       -                        img->data[b++] = bg.green / 257;
       -                        img->data[b++] = bg.red / 257;
       -                        b++;
       -                }
       -        }
       -
       -        LtkTextSegment *ts = tl->start_segment;
       -        int x = 0;
       -        int y = 0;
       -        int is_hor = HB_DIRECTION_IS_HORIZONTAL(ts->dir);
       -        do {
       -                if (is_hor) {
       -                        y = tl->h - tl->y_max;
       -                        ltk_render_text_segment(ts, x + ts->start_x, y, img, fg);
       -                        x += ts->w;
       -                } else {
       -                        x = tl->w - tl->x_max;
       -                        ltk_render_text_segment(ts, x, y + ts->start_y, img, fg);
       -                        y += ts->h;
       -                }
       -        } while (ts = ts->next);
       -
       -        return img;
       -}
       -
       -void
       -ltk_render_text_segment(
       -        LtkTextSegment *ts,
       -        unsigned int start_x,
       -        unsigned int start_y,
       -        XImage *img,
       -        XColor fg)
       -{
       -        LtkGlyph *glyph = ts->start_glyph;
       -        int x_cur = start_x;
       -        int y_cur = start_y;
       -        int x, y;
       -        double a;
       -        int b;
       -        do {
       -                x = x_cur + glyph->info->xoff + glyph->x_offset;
       -                y = y_cur + glyph->info->yoff - glyph->y_offset;
       -                for (int i = 0; i < glyph->info->h; i++) {
       -                        for (int j = 0; j < glyph->info->w; j++) {
       -                                b = (y + i) * img->bytes_per_line + (x + j) * 4;
       -                                a = glyph->info->alphamap[i * glyph->info->w + j] / 255.0;
       -                                img->data[b] = (fg.blue * a + (1 - a) * (uint16_t)img->data[b] * 257) / 257;
       -                                img->data[b + 1] = (fg.green * a + (1 - a) * (uint16_t)img->data[b + 1] * 257) / 257;
       -                                img->data[b + 2] = (fg.red * a + (1 - a) * (uint16_t)img->data[b + 2] * 257) / 257;
       -                        }
       -                }
       -                x_cur += glyph->x_advance;
       -                y_cur -= glyph->y_advance;
       -        } while (glyph = glyph->next);
       -}
       -#endif
   DIR diff --git a/text_buffer.c b/text_buffer.c
       t@@ -34,7 +34,7 @@
        #include <fribidi.h>
        #include <harfbuzz/hb.h>
        #include <harfbuzz/hb-ot.h>
       -#include "text-common.h"
       +#include "text_common.h"
        #include "array.h"
        #include "text_buffer.h"
        #include "ltk.h"
   DIR diff --git a/text_buffer.h b/text_buffer.h
       t@@ -28,7 +28,7 @@
        Requires the following includes:
        <X11/Xlib.h>, <X11/Xutil.h>, "stb_truetype.h",
        "khash.h", <harfbuzz/hb.h>, <fribidi.h>,
       -<fontconfig/fontconfig.h>
       +<fontconfig/fontconfig.h>, "text_common.h"
        */
        
        /* Note: hb_script_t and FriBidiLevel are really just uint32_t's, but
   DIR diff --git a/text_common.c b/text_common.c
       t@@ -0,0 +1,410 @@
       +/*
       + * This file is part of the Lumidify ToolKit (LTK)
       + * Copyright (c) 2017, 2018, 2020 lumidify <nobody@lumidify.org>
       + *
       + * Permission is hereby granted, free of charge, to any person obtaining a copy
       + * of this software and associated documentation files (the "Software"), to deal
       + * in the Software without restriction, including without limitation the rights
       + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       + * copies of the Software, and to permit persons to whom the Software is
       + * furnished to do so, subject to the following conditions:
       + *
       + * The above copyright notice and this permission notice shall be included in all
       + * copies or substantial portions of the Software.
       + *
       + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
       + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
       + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
       + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
       + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
       + * SOFTWARE.
       + */
       +
       +#include <stdio.h>
       +#include <stdlib.h>
       +#include <stdint.h>
       +#include <limits.h>
       +#include <X11/Xlib.h>
       +#include <X11/Xutil.h>
       +#include "stb_truetype.h" /* http://nothings.org/stb/stb_truetype.h */
       +#include <fontconfig/fontconfig.h>
       +#include "khash.h"
       +#include <fribidi.h>
       +#include <harfbuzz/hb.h>
       +#include <harfbuzz/hb-ot.h>
       +#include "text_common.h"
       +#include "ltk.h"
       +
       +extern Ltk *ltk_global;
       +
       +/* These unicode routines are taken from
       + * https://github.com/JeffBezanson/cutef8 */
       +
       +/* is c the start of a utf8 sequence? */
       +#define isutf(c) (((c)&0xC0)!=0x80)
       +
       +static const uint32_t offsetsFromUTF8[6] = {
       +    0x00000000UL, 0x00003080UL, 0x000E2080UL,
       +    0x03C82080UL, 0xFA082080UL, 0x82082080UL
       +};
       +
       +/* next character without NUL character terminator */
       +uint32_t u8_nextmemchar(const char *s, size_t *i)
       +{
       +    uint32_t ch = 0;
       +    size_t sz = 0;
       +    do {
       +        ch <<= 6;
       +        ch += (unsigned char)s[(*i)++];
       +        sz++;
       +    } while (!isutf(s[*i]));
       +    ch -= offsetsFromUTF8[sz-1];
       +
       +    return ch;
       +}
       +
       +/* number of characters in NUL-terminated string */
       +size_t u8_strlen(const char *s)
       +{
       +    size_t count = 0;
       +    size_t i = 0, lasti;
       +
       +    while (1) {
       +        lasti = i;
       +        while (s[i] > 0)
       +            i++;
       +        count += (i-lasti);
       +        if (s[i++]==0) break;
       +        (void)(isutf(s[++i]) || isutf(s[++i]) || ++i);
       +        count++;
       +    }
       +    return count;
       +}
       +
       +size_t u8_wc_toutf8(char *dest, uint32_t ch)
       +{
       +    if (ch < 0x80) {
       +        dest[0] = (char)ch;
       +        return 1;
       +    }
       +    if (ch < 0x800) {
       +        dest[0] = (ch>>6) | 0xC0;
       +        dest[1] = (ch & 0x3F) | 0x80;
       +        return 2;
       +    }
       +    if (ch < 0x10000) {
       +        dest[0] = (ch>>12) | 0xE0;
       +        dest[1] = ((ch>>6) & 0x3F) | 0x80;
       +        dest[2] = (ch & 0x3F) | 0x80;
       +        return 3;
       +    }
       +    if (ch < 0x110000) {
       +        dest[0] = (ch>>18) | 0xF0;
       +        dest[1] = ((ch>>12) & 0x3F) | 0x80;
       +        dest[2] = ((ch>>6) & 0x3F) | 0x80;
       +        dest[3] = (ch & 0x3F) | 0x80;
       +        return 4;
       +    }
       +    return 0;
       +}
       +
       +LtkTextManager *
       +ltk_init_text(char *font_name)
       +{
       +        LtkTextManager *tm = malloc(sizeof(LtkTextManager));
       +        if (!tm) {
       +                (void)printf("Memory exhausted when trying to create text manager.");
       +                exit(1);
       +        }
       +        tm->font_paths = kh_init(fontid);
       +        tm->font_cache = kh_init(fontstruct);
       +        tm->glyph_cache = kh_init(glyphcache);
       +        /* FIXME: THIS REALLY SHOULD NOT BE UINT16_T! IT GETS MESSY WITH BIT-SHIFTING */
       +        tm->font_id_cur = 1;
       +        ltk_load_default_font(tm, font_name);
       +
       +        return tm;
       +}
       +
       +void
       +ltk_destroy_text_manager(LtkTextManager *tm)
       +{
       +        int k;
       +
       +        kh_destroy(fontid, tm->font_paths);
       +
       +        for (k = kh_begin(tm->font_cache); k != kh_end(tm->font_cache); k++) {
       +                if (kh_exist(tm->font_cache, k)) {
       +                        ltk_destroy_font(kh_value(tm->font_cache, k));
       +                }
       +        }
       +        kh_destroy(fontstruct, tm->font_cache);
       +
       +        for (k = kh_begin(tm->glyph_cache); k != kh_end(tm->glyph_cache); k++) {
       +                if (kh_exist(tm->glyph_cache, k)) {
       +                        ltk_destroy_glyph_cache(kh_value(tm->glyph_cache, k));
       +                }
       +        }
       +        kh_destroy(glyphcache, tm->glyph_cache);
       +
       +        free(tm);
       +}
       +
       +LtkGlyphInfo *
       +ltk_create_glyph_info(LtkFont *font, unsigned int id, float scale)
       +{
       +        LtkGlyphInfo *glyph = malloc(sizeof(LtkGlyphInfo));
       +        if (!glyph) {
       +                (void)printf("Out of memory!\n");
       +                exit(1);
       +        }
       +
       +        glyph->id = id;
       +        glyph->refs = 0;
       +        glyph->alphamap = stbtt_GetGlyphBitmap(
       +                &font->info, scale, scale, id, &glyph->w,
       +                &glyph->h, &glyph->xoff, &glyph->yoff
       +        );
       +
       +        return glyph;
       +}
       +
       +void
       +ltk_destroy_glyph_info(LtkGlyphInfo *gi)
       +{
       +        free(gi->alphamap);
       +        free(gi);
       +}
       +
       +LtkGlyphInfo *
       +ltk_get_glyph_info(LtkFont *font, unsigned int id, float scale, khash_t(glyphinfo) *cache)
       +{
       +        int ret;
       +        khint_t k;
       +        LtkGlyphInfo *glyph;
       +        k = kh_get(glyphinfo, cache, id);
       +        if (k == kh_end(cache)) {
       +                glyph = ltk_create_glyph_info(font, id, scale);
       +                /* FIXME: error checking with ret */
       +                k = kh_put(glyphinfo, cache, id, &ret);
       +                kh_value(cache, k) = glyph;
       +        } else {
       +                glyph = kh_value(cache, k);
       +        }
       +
       +        return glyph;
       +}
       +
       +khint_t
       +ltk_create_glyph_cache(LtkTextManager *tm, uint16_t font_id, uint16_t font_size)
       +{
       +        khash_t(glyphinfo) *cache = kh_init(glyphinfo);
       +        int ret;
       +        khint_t k;
       +        /* I guess I can just ignore ret for now */
       +        k = kh_put(glyphcache, tm->glyph_cache, font_id << 16 + font_size, &ret);
       +        kh_value(tm->glyph_cache, k) = cache;
       +
       +        return k;
       +}
       +
       +void
       +ltk_destroy_glyph_cache(khash_t(glyphinfo) *cache)
       +{
       +        int k;
       +        for (k = kh_begin(cache); k != kh_end(cache); k++) {
       +                if (kh_exist(cache, k)) {
       +                        ltk_destroy_glyph_info(kh_value(cache, k));
       +                }
       +        }
       +        kh_destroy(glyphinfo, cache);
       +}
       +
       +void
       +ltk_load_default_font(LtkTextManager *tm, char *name)
       +{
       +        FcPattern *match;
       +        FcResult result;
       +        char *file;
       +        int index;
       +        uint16_t font;
       +
       +        tm->fcpattern = FcNameParse(name);
       +        FcPatternAddString(tm->fcpattern, FC_FONTFORMAT, "truetype");
       +        FcConfigSubstitute(NULL, tm->fcpattern, FcMatchPattern);
       +        FcDefaultSubstitute(tm->fcpattern);
       +        match = FcFontMatch(NULL, tm->fcpattern, &result);
       +
       +        FcPatternGetString (match, FC_FILE, 0, (FcChar8 **) &file);
       +        /* FIXME: Why is index never used? This is the index within the font file,
       +           so it might be important, although I'm not sure if stb_truetype even
       +           supports it */
       +        FcPatternGetInteger (match, FC_INDEX, 0, &index);
       +
       +        tm->default_font = ltk_get_font(tm, file);
       +
       +        FcPatternDestroy (match);
       +}
       +
       +LtkFont *
       +ltk_create_font(char *path, uint16_t id)
       +{
       +        long len;
       +        LtkFont *font = malloc(sizeof(LtkFont));
       +        if (!font) {
       +                (void)fprintf(stderr, "Out of memory!\n");
       +                exit(1);
       +        }
       +        char *contents = ltk_read_file(path, &len);
       +        if (!stbtt_InitFont(&font->info, contents, 0))
       +        {
       +                (void)fprintf(stderr, "Failed to load font %s\n", path);
       +                exit(1);
       +        }
       +        /* FIXME: make use of the destroy function (last argument to hb_blob_create - see hb-blob.cc in harfbuzz source) */
       +        hb_blob_t *blob = hb_blob_create(contents, len, HB_MEMORY_MODE_READONLY, NULL, NULL);
       +        hb_face_t *face = hb_face_create(blob, 0);
       +        /* FIXME: need to use destroy function in order for the original file data to be freed? */
       +        hb_blob_destroy(blob);
       +        font->hb = hb_font_create(face);
       +        hb_face_destroy(face);
       +        hb_ot_font_set_funcs(font->hb);
       +        font->id = id;
       +        font->refs = 0;
       +
       +        return font;
       +}
       +
       +void
       +ltk_destroy_font(LtkFont *font)
       +{
       +        free(font->info.data);
       +        hb_font_destroy(font->hb);
       +        free(font);
       +}
       +
       +uint16_t
       +ltk_load_font(LtkTextManager *tm, char *path)
       +{
       +        LtkFont *font = ltk_create_font(path, tm->font_id_cur++);
       +        int ret;
       +        khint_t k;
       +        /* FIXME: does kh_destroy also free these copied strings properly? */
       +        char *key = strdup(path);
       +        k = kh_put(fontid, tm->font_paths, key, &ret);
       +        kh_value(tm->font_paths, k) = font->id;
       +        k = kh_put(fontstruct, tm->font_cache, (khint_t) font->id, &ret);
       +        kh_value(tm->font_cache, k) = font;
       +        k = kh_get(fontid, tm->font_paths, path);
       +
       +        return font->id;
       +}
       +
       +uint16_t
       +ltk_get_font(LtkTextManager *tm, char *path)
       +{
       +        int ret;
       +        khint_t k;
       +        uint16_t id;
       +        k = kh_get(fontid, tm->font_paths, path);
       +        if (k == kh_end(tm->font_paths)) {
       +                id = ltk_load_font(tm, path);
       +        } else {
       +                id = kh_value(tm->font_paths, k);
       +        }
       +
       +        return id;
       +}
       +
       +void
       +ltk_destroy_glyph(LtkGlyph *glyph, khash_t(glyphinfo) *cache)
       +{
       +        int k;
       +        if (--glyph->info->refs < 1) {
       +                k = kh_get(glyphinfo, cache, glyph->info->id);
       +                kh_del(glyphinfo, cache, k);
       +                ltk_destroy_glyph_info(glyph->info);
       +        }
       +        free(glyph);
       +}
       +
       +#if 0
       +/* based on http://codemadness.org/git/dwm-font/file/drw.c.html#l315 */
       +XImage *
       +ltk_render_text_line(
       +        LtkTextLine *tl,
       +        Display *dpy,
       +        Window window,
       +        GC gc,
       +        Colormap colormap,
       +        XColor fg,
       +        XColor bg)
       +{
       +        XWindowAttributes attrs;
       +        XGetWindowAttributes(dpy, window, &attrs);
       +        int depth = attrs.depth;
       +        XImage *img = XCreateImage(dpy, CopyFromParent, depth, ZPixmap, 0, NULL, tl->w, tl->h, 32, 0);
       +        img->data = calloc(img->bytes_per_line, img->height);
       +        XInitImage(img);
       +        int b;
       +        for (int i = 0; i < tl->h; i++) {
       +                b = img->bytes_per_line * i;
       +                for (int j = 0; j < tl->w; j++) {
       +                        img->data[b++] = bg.blue / 257;
       +                        img->data[b++] = bg.green / 257;
       +                        img->data[b++] = bg.red / 257;
       +                        b++;
       +                }
       +        }
       +
       +        LtkTextSegment *ts = tl->start_segment;
       +        int x = 0;
       +        int y = 0;
       +        int is_hor = HB_DIRECTION_IS_HORIZONTAL(ts->dir);
       +        do {
       +                if (is_hor) {
       +                        y = tl->h - tl->y_max;
       +                        ltk_render_text_segment(ts, x + ts->start_x, y, img, fg);
       +                        x += ts->w;
       +                } else {
       +                        x = tl->w - tl->x_max;
       +                        ltk_render_text_segment(ts, x, y + ts->start_y, img, fg);
       +                        y += ts->h;
       +                }
       +        } while (ts = ts->next);
       +
       +        return img;
       +}
       +
       +void
       +ltk_render_text_segment(
       +        LtkTextSegment *ts,
       +        unsigned int start_x,
       +        unsigned int start_y,
       +        XImage *img,
       +        XColor fg)
       +{
       +        LtkGlyph *glyph = ts->start_glyph;
       +        int x_cur = start_x;
       +        int y_cur = start_y;
       +        int x, y;
       +        double a;
       +        int b;
       +        do {
       +                x = x_cur + glyph->info->xoff + glyph->x_offset;
       +                y = y_cur + glyph->info->yoff - glyph->y_offset;
       +                for (int i = 0; i < glyph->info->h; i++) {
       +                        for (int j = 0; j < glyph->info->w; j++) {
       +                                b = (y + i) * img->bytes_per_line + (x + j) * 4;
       +                                a = glyph->info->alphamap[i * glyph->info->w + j] / 255.0;
       +                                img->data[b] = (fg.blue * a + (1 - a) * (uint16_t)img->data[b] * 257) / 257;
       +                                img->data[b + 1] = (fg.green * a + (1 - a) * (uint16_t)img->data[b + 1] * 257) / 257;
       +                                img->data[b + 2] = (fg.red * a + (1 - a) * (uint16_t)img->data[b + 2] * 257) / 257;
       +                        }
       +                }
       +                x_cur += glyph->x_advance;
       +                y_cur -= glyph->y_advance;
       +        } while (glyph = glyph->next);
       +}
       +#endif
   DIR diff --git a/text-common.h b/text_common.h
   DIR diff --git a/text_edit.c b/text_edit.c
       t@@ -31,7 +31,7 @@
        #include <fribidi.h>
        #include <harfbuzz/hb.h>
        #include <fontconfig/fontconfig.h>
       -#include "text-common.h"
       +#include "text_common.h"
        #include "array.h"
        #include "text_buffer.h"
        #include "text_edit.h"
   DIR diff --git a/tmpfb.txt b/tmpfb.txt
       t@@ -1,67 +0,0 @@
       -49
       -27
       -6d
       -20
       -61
       -20
       -62
       -75
       -74
       -74
       -6f
       -6e
       -21
       -0
       -49
       -27
       -6d
       -20
       -61
       -20
       -62
       -75
       -74
       -74
       -6f
       -6e
       -21
       -0
       -49
       -27
       -6d
       -20
       -61
       -20
       -62
       -75
       -74
       -74
       -6f
       -6e
       -21
       -0
       -6c1
       -645
       -627
       -631
       -6d2
       -20
       -628
       -627
       -631
       -6d2
       -20
       -645
       -6cc
       -6ba
       -20
       -62
       -6c
       -61
       -62
       -6c
       -61
       -62
       -6c
       -61
       -0
   DIR diff --git a/tmpnofb.txt b/tmpnofb.txt
       t@@ -1,63 +0,0 @@
       -49
       -27
       -6d
       -20
       -61
       -20
       -62
       -75
       -74
       -74
       -6f
       -6e
       -21
       -0
       -49
       -27
       -6d
       -20
       -61
       -20
       -62
       -75
       -74
       -74
       -6f
       -6e
       -21
       -0
       -49
       -27
       -6d
       -20
       -61
       -20
       -62
       -75
       -74
       -74
       -6f
       -6e
       -21
       -0
       -62
       -6c
       -61
       -62
       -6c
       -61
       -62
       -6c
       -61
       -20
       -fb9f
       -fbff
       -fee3
       -20
       -fbae
       -fead
       -fe8e
       -fe91
       -20
       -fbae
       -fead
   DIR diff --git a/Lumidify_Casual.ttf b/unused/Lumidify_Casual.ttf
       Binary files differ.
   DIR diff --git a/gap_buffer.h b/unused/gap_buffer.h
   DIR diff --git a/main.c b/unused/main.c
   DIR diff --git a/stack.h b/unused/stack.h
   DIR diff --git a/text-hb.c b/unused/text-hb.c
   DIR diff --git a/text-hb.h b/unused/text-hb.h
   DIR diff --git a/text.c b/unused/text.c
   DIR diff --git a/text.c.bak b/unused/text.c.bak
   DIR diff --git a/text.h b/unused/text.h
   DIR diff --git a/text/Awami_beta3.ttf b/unused/text/Awami_beta3.ttf
       Binary files differ.
   DIR diff --git a/text/FONTLOG.txt b/unused/text/FONTLOG.txt
   DIR diff --git a/text/GENTIUM-FAQ.txt b/unused/text/GENTIUM-FAQ.txt
   DIR diff --git a/text/GentiumPlus-I.ttf b/unused/text/GentiumPlus-I.ttf
       Binary files differ.
   DIR diff --git a/text/GentiumPlus-R.ttf b/unused/text/GentiumPlus-R.ttf
       Binary files differ.
   DIR diff --git a/text/LICENSE_OFL.txt b/unused/text/LICENSE_OFL.txt
   DIR diff --git a/text/Makefile b/unused/text/Makefile
   DIR diff --git a/text/NotoNastaliqUrdu-Regular.ttf b/unused/text/NotoNastaliqUrdu-Regular.ttf
       Binary files differ.
   DIR diff --git a/text/OFL-FAQ.txt b/unused/text/OFL-FAQ.txt
   DIR diff --git a/text/OFL.txt b/unused/text/OFL.txt
   DIR diff --git a/text/README b/unused/text/README
   DIR diff --git a/text/README.txt b/unused/text/README.txt
   DIR diff --git a/text/bob.c b/unused/text/bob.c
   DIR diff --git a/text/font.ttf b/unused/text/font.ttf
       Binary files differ.
   DIR diff --git a/text/font1.ttf b/unused/text/font1.ttf
       Binary files differ.
   DIR diff --git a/text/font2.ttf b/unused/text/font2.ttf
       Binary files differ.
   DIR diff --git a/text/hashtest.c b/unused/text/hashtest.c
   DIR diff --git a/text/khash.h b/unused/text/khash.h
   DIR diff --git a/text/main.c b/unused/text/main.c
   DIR diff --git a/text/main1.c b/unused/text/main1.c
   DIR diff --git a/text/new.c b/unused/text/new.c
   DIR diff --git a/text/stb_image_write.h b/unused/text/stb_image_write.h
   DIR diff --git a/text/stb_truetype.h b/unused/text/stb_truetype.h
   DIR diff --git a/text/test.c b/unused/text/test.c
   DIR diff --git a/text/test23.c b/unused/text/test23.c
   DIR diff --git a/text/test3.c b/unused/text/test3.c
   DIR diff --git a/text/text-hb.c b/unused/text/text-hb.c
   DIR diff --git a/text/text-hb.new.c b/unused/text/text-hb.new.c
   DIR diff --git a/text/text-hb.ubernew.c b/unused/text/text-hb.ubernew.c
   DIR diff --git a/text/text-hb.uberubernew.c b/unused/text/text-hb.uberubernew.c
   DIR diff --git a/text/text.c b/unused/text/text.c
   DIR diff --git a/text/text1.c b/unused/text/text1.c
   DIR diff --git a/text/text2.c b/unused/text/text2.c
   DIR diff --git a/text/tmp.c b/unused/text/tmp.c
   DIR diff --git a/text/utf8.c b/unused/text/utf8.c
   DIR diff --git a/text/utf8.h b/unused/text/utf8.h
   DIR diff --git a/text/utf8_new.c b/unused/text/utf8_new.c
   DIR diff --git a/theme.c b/unused/theme.c
   DIR diff --git a/theme.h b/unused/theme.h