URI: 
       text.c.bak - ltkx - GUI toolkit for X11 (old)
  HTML git clone git://lumidify.org/ltkx.git (fast, but not encrypted)
  HTML git clone https://lumidify.org/ltkx.git (encrypted, but very slow)
  HTML git clone git://4kcetb7mo7hj6grozzybxtotsub5bempzo4lirzc3437amof2c2impyd.onion/ltkx.git (over tor)
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       text.c.bak (4686B)
       ---
            1 /*
            2  * This file is part of the Lumidify ToolKit (LTK)
            3  * Copyright (c) 2016, 2017 Lumidify Productions <lumidify@openmailbox.org>
            4  *
            5  * Permission is hereby granted, free of charge, to any person obtaining a copy
            6  * of this software and associated documentation files (the "Software"), to deal
            7  * in the Software without restriction, including without limitation the rights
            8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
            9  * copies of the Software, and to permit persons to whom the Software is
           10  * furnished to do so, subject to the following conditions:
           11  *
           12  * The above copyright notice and this permission notice shall be included in all
           13  * copies or substantial portions of the Software.
           14  *
           15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
           16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
           17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
           18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
           19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
           20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
           21  * SOFTWARE.
           22  */
           23 
           24 #include <stdio.h>
           25 #include <stdlib.h>
           26 #include <stdint.h>
           27 #include <X11/Xlib.h>
           28 #include <X11/Xutil.h>
           29 #include "text.h"
           30 
           31 uint32_t u8_nextmemchar(const char *s, size_t *i)
           32 {
           33     uint32_t ch = 0;
           34     size_t sz = 0;
           35     do {
           36         ch <<= 6;
           37         ch += (unsigned char)s[(*i)++];
           38         sz++;
           39     } while (!isutf(s[*i]));
           40     ch -= offsetsFromUTF8[sz-1];
           41 
           42     return ch;
           43 }
           44 
           45 stbtt_fontinfo ltk_load_font(const char *path)
           46 {
           47         FILE *f;
           48         long len;
           49         char *contents;
           50         stbtt_fontinfo info;
           51         f = fopen(path, "rb");
           52         fseek(f, 0, SEEK_END);
           53         len = ftell(f);
           54         fseek(f, 0, SEEK_SET);
           55         contents = malloc(len + 1);
           56         fread(contents, 1, len, f);
           57         contents[len] = '\0';
           58         fclose(f);
           59         if (!stbtt_InitFont(&info, contents, 0))
           60         {
           61                 fprintf(stderr, "Failed to load font %s\n", path);
           62                 exit(1);
           63         }
           64         return info;
           65 }
           66 
           67 int ltk_text_width(uint8_t *text, stbtt_fontinfo fontinfo, int height)
           68 {
           69         float scale = stbtt_ScaleForPixelHeight(&fontinfo, height);
           70         size_t i = 0;
           71         int length = strlen(text);
           72         if (length < 1) return 0;
           73         int temp_x;
           74         int kern_advance;
           75         int width = 0;
           76         uint32_t char1;
           77         uint32_t char2;
           78         char1 = u8_nextmemchar(text, &i);
           79         while(i <= length)
           80         {
           81                 stbtt_GetCodepointHMetrics(&fontinfo, char1, &temp_x, 0);
           82                 width += temp_x * scale;
           83 
           84                 char2 = u8_nextmemchar(text, &i);
           85                 if (!char2) break;
           86                 kern_advance = stbtt_GetCodepointKernAdvance(&fontinfo, char1, char2);
           87                 width += kern_advance * scale;
           88                 char1 = char2;
           89         }
           90 
           91         return width;
           92 }
           93 
           94 Pixmap ltk_render_text(
           95         Display *display,
           96         Window window,
           97         GC gc,
           98         uint8_t *text,
           99         stbtt_fontinfo fontinfo,
          100         int height,
          101         unsigned long fg,
          102         unsigned long bg)
          103 {
          104         XWindowAttributes attrs;
          105         XGetWindowAttributes(display, window, &attrs);
          106         int depth = attrs.depth;
          107 
          108         int width = ltk_text_width(text, fontinfo, height);
          109         unsigned char *bitmap = calloc(sizeof(char), width * height);
          110         float scale = stbtt_ScaleForPixelHeight(&fontinfo, height);
          111 
          112         int ascent, descent, line_gap;
          113         stbtt_GetFontVMetrics(&fontinfo, &ascent, &descent, &line_gap);
          114         ascent *= scale;
          115         descent *= scale;
          116 
          117         size_t i = 0;
          118         int length = strlen(text);
          119         if (length < 1)
          120         {
          121                 printf("WARNING: ltk_render_text: length of text is less than 1.\n");
          122                 return XCreatePixmap(display, window, 0, 0, depth);
          123         }
          124         uint32_t char1, char2;
          125         char1 = u8_nextmemchar(text, &i);
          126         int ax, x = 0, y, x1, y1, x2, y2, byte_offset, kern_advance;
          127         while (i <= length)
          128         {
          129                 stbtt_GetCodepointBitmapBox(&fontinfo, char1, scale, scale, &x1, &y1, &x2, &y2);
          130                 y = ascent + y1;
          131                 byte_offset = x + (y  * width);
          132                 stbtt_MakeCodepointBitmap(&fontinfo, bitmap + byte_offset, x2 - x1, y2 - y1, width, scale, scale, char1);
          133 
          134                 stbtt_GetCodepointHMetrics(&fontinfo, char1, &ax, 0);
          135                 x += ax * scale;
          136 
          137                 char2 = u8_nextmemchar(text, &i);
          138                 if (!char2) break;
          139                 kern_advance = stbtt_GetCodepointKernAdvance(&fontinfo, char1, char2);
          140                 x += kern_advance * scale;
          141                 char1 = char2;
          142         }
          143 
          144         /* TODO: separate this into a separate function so that one function only creates
          145          * the bitmap and other functions to turn that into a pixmap with solid color
          146          * background, image background, etc.
          147          */
          148         Pixmap rendered = XCreatePixmap(display, window, width, height, depth);
          149         XSetForeground(display, gc, bg);
          150         for (int i = 0; i < height; i++)
          151         {
          152                 for (int j = 0; j < width; j++)
          153                 {
          154                         /* Yay! Magic! */
          155                         XSetForeground(display, gc, (bitmap[i * width + j] / 255.0) * fg + ((255 - bitmap[i * width + j]) / 255.0) * bg);
          156                         XDrawPoint(display, rendered, gc, j, i);
          157                 }
          158         }
          159         XSetForeground(display, gc, bg);
          160         return rendered;
          161 }