*** empty log message ***
[m17n/libotf.git] / example / otfview.c
index 2680d73..aae4f94 100644 (file)
@@ -9,20 +9,21 @@
 #include <ft2build.h>
 #include FT_FREETYPE_H
 
-FT_Library library;
-FT_Face face;
-
 #include <X11/Xlib.h>
 #include <X11/keysym.h>
 #include <X11/Xutil.h>
 
-#define PIXEL_SIZE 20
+#define PIXEL_SIZE 40
 
 //#define FONT_NAME "-adobe-courier-medium-r-normal--12-120-75-75-m-70-iso8859-1"
 #define FONT_NAME "6x13"
 #define FONT_HEIGHT 14
+
 int font_height, font_width;
 
+FT_Library library;
+FT_Face face;
+
 Display *display;
 int screen;
 Window win;
@@ -34,6 +35,7 @@ XGCValues values;
 
 typedef struct
 {
+  int advance;
   int left, top;
   int rows;
   int width;
@@ -48,19 +50,16 @@ Bitmap bitmap[0x10000];
 int utog[0x10000];
 
 void
-draw_bitmap (int index, int x, int xoff, int width,
-            int y, int yoff, int height, int clear)
+draw_bitmap (int index, int x, int y)
 {
   Bitmap *bmp = bitmap + index;
   unsigned char *buf = bmp->buf;
   int i, j;
 
-  if (clear)
-    XClearArea (display, win, x, y, width, height, False);
   if (buf)
     {
-      x += xoff + bmp->left;
-      y += yoff - bmp->top;
+      x += bmp->left;
+      y -= bmp->top;
       for (i = 0; i < bmp->rows; i++, buf += bmp->pitch)
        for (j = 0; j < bmp->width; j++)
          if (buf[j / 8] & (1 << (7 - (j % 8))))
@@ -69,31 +68,6 @@ draw_bitmap (int index, int x, int xoff, int width,
 }
 
 void
-draw_big_bitmat (int index,
-                int x, int xoff, int width,
-                int y, int yoff, int height)
-{
-  FT_Bitmap *bmp;
-  unsigned char *buf;
-  int i, j;
-
-  FT_Set_Pixel_Sizes (face, 0, PIXEL_SIZE * 4);
-  if (FT_Load_Glyph (face, index, FT_LOAD_RENDER | FT_LOAD_MONOCHROME))
-    return;
-  
-  bmp = &face->glyph->bitmap;
-  buf = bmp->buffer;
-  XFillRectangle (display, win, gc_rev, x, y, width, height);
-  XDrawRectangle (display, win, gc_norm, x - 1, y - 1, width + 1, height + 1);
-  x += xoff + face->glyph->bitmap_left;
-  y += yoff - face->glyph->bitmap_top;
-  for (i = 0; i < bmp->rows; i++, buf += bmp->pitch)
-    for (j = 0; j < bmp->width; j++)
-      if (buf[j / 8] & (1 << (7 - (j % 8))))
-       XDrawPoint (display, win, gc_norm, x + j, y + i);
-}
-
-void
 quit (char *msg)
 {
   fprintf (stderr, "Error by %s\n", msg);
@@ -127,7 +101,6 @@ main (int argc, char **argv)
   int err;
   int i, j, max_glyph_idx;
   int first_idx;
-  int left_idx = -1, right_idx = -1;
   int update_mask;
 #define UPDATE_RENDERING 1
 #define UPDATE_BITMAP 2
@@ -135,6 +108,8 @@ main (int argc, char **argv)
   OTF_Glyph *g;
   int unicode_seq[256];
   int n_codes = 0;
+  int pixel_size = PIXEL_SIZE;
+
   /* Window structure.
 
   +-------------------------+
@@ -170,12 +145,22 @@ main (int argc, char **argv)
     }
   
   otf = OTF_open (argv[1]);
-  if (! otf)
+  if (! otf
+      || OTF_get_table (otf, "head") < 0
+      || OTF_get_table (otf, "cmap") < 0)
     {
       OTF_perror ("otfview");
       exit (1);
     }
 
+  {
+    char *p = getenv ("PIXEL_SIZE");
+    int n;
+
+    if (p && sscanf (p, "%d", &n) == 1)
+      pixel_size = n;
+  }
+
   err = FT_Init_FreeType (&library);
   if (err)
     quit ("FT_Init_FreeType");
@@ -184,7 +169,7 @@ main (int argc, char **argv)
     quit ("FT_New_Face: unknown file format");
   else if (err)
     quit ("FT_New_Face: unknown error");
-  err = FT_Set_Pixel_Sizes (face, 0, PIXEL_SIZE);
+  err = FT_Set_Pixel_Sizes (face, 0, pixel_size);
   if (err)
     quit ("FT_Set_Char_Size");
 
@@ -201,6 +186,7 @@ main (int argc, char **argv)
          int bmpsize;
 
          max_glyph_idx = i;
+         bmp->advance = face->glyph->metrics.horiAdvance >> 6;
          bmp->left = face->glyph->bitmap_left;
          bmp->top = face->glyph->bitmap_top;
          bmp->rows = face->glyph->bitmap.rows;
@@ -225,6 +211,8 @@ main (int argc, char **argv)
 
   for (i = 0; i < 0x10000; i++)
     {
+      if (i >= 0xD800 && i < 0xE000)
+       continue;
       gstring.glyphs[i & 0xFF].c = i;
       if ((i & 0xFF) == 0xFF)
        {
@@ -232,7 +220,8 @@ main (int argc, char **argv)
          for (j = 0; j < 0x100; j++)
            {
              utog[(i & 0xFF00) + j] = gstring.glyphs[j].glyph_id;
-             if (gstring.glyphs[j].glyph_id > 0)
+             if (gstring.glyphs[j].glyph_id > 0
+                 && gstring.glyphs[j].glyph_id < 0x10000)
                bitmap[gstring.glyphs[j].glyph_id].unicode = (i & 0xFF00) + j;
            }
        }
@@ -395,22 +384,49 @@ main (int argc, char **argv)
 
          OTF_drive_cmap (otf, &gstring);
          y = margin + font_height + 1;
-         for (i = 0; i < n_codes; i++, x+= max_glyph_width)
-           draw_bitmap (gstring.glyphs[i].glyph_id, x, -x0, max_glyph_width,
-                        y, -y0, max_glyph_height, 1);
+         for (i = 0; i < n_codes; i++, x += max_glyph_width)
+           draw_bitmap (gstring.glyphs[i].glyph_id, x - x0, y - y0);
 
          OTF_drive_gsub (otf, &gstring, "deva", NULL, NULL);
          x = margin + font_width * 9;
          y += max_glyph_height;
+         for (i = 0; i < gstring.used; i++, x += max_glyph_width)
+           draw_bitmap (gstring.glyphs[i].glyph_id, x - x0, y - y0);
+
+         OTF_drive_gpos (otf, &gstring, "deva", NULL, NULL);
+         x = margin + font_width * 9 - x0;
+         y += max_glyph_height - y0;
          for (i = 0; i < gstring.used; i++)
            {
-             draw_bitmap (gstring.glyphs[i].glyph_id, x, -x0, max_glyph_width,
-                          y, -y0, max_glyph_height, 0);
-             x += bitmap[gstring.glyphs[i].glyph_id].width;
+             int xoff = 0, yoff = 0;
+             OTF_Glyph *g = gstring.glyphs + i;
+
+             switch (g->positioning_type)
+               {
+               case 1: case 2:
+                 if (g->f.f1.format & OTF_XPlacement)
+                   xoff = pixel_size * ((double) (g->f.f1.value->XPlacement)
+                                        * 100 / otf->head->unitsPerEm);
+                 if (g->f.f1.format & OTF_YPlacement)
+                   yoff = pixel_size * ((double) (g->f.f1.value->YPlacement)
+                                        * 100 / otf->head->unitsPerEm);
+                 break;
+
+               case 4:
+                 xoff = (pixel_size
+                         * ((double) (g->f.f4.base_anchor->XCoordinate
+                                      - g->f.f4.mark_anchor->XCoordinate)
+                            * 100 / otf->head->unitsPerEm));
+                 yoff = (pixel_size
+                         * ((double) (g->f.f4.base_anchor->YCoordinate
+                                      - g->f.f4.mark_anchor->YCoordinate)
+                            * 100 / otf->head->unitsPerEm));
+                 break;
+               }
+
+             draw_bitmap (gstring.glyphs[i].glyph_id, x + xoff, y + yoff);
+             x += bitmap[gstring.glyphs[i].glyph_id].advance;
            }
-
-         draw_big_bitmat (left_idx, max_glyph_width * 2, -x0 * 5, max_glyph_width * 5,
-                          5, -y0 * 5, max_glyph_height * 5);
        }
 
       if (update_mask & UPDATE_BITMAP)
@@ -427,10 +443,14 @@ main (int argc, char **argv)
          y = margin * 2 + rendering_area_height + font_height + 2;
          for (i = 0; i < rows; i++)
            for (j = 0; j < cols; j++)
-             draw_bitmap (first_idx + i * cols + j,
-                          x + (max_glyph_width + 1) * j, -x0, max_glyph_width,
-                          y + (max_glyph_height + 1) * i,
-                          -y0, max_glyph_height, 1);
+             {
+               XClearArea (display, win, x + (max_glyph_width + 1) * j,
+                           y + (max_glyph_height + 1) * i,
+                           max_glyph_width, max_glyph_height, False);
+               draw_bitmap (first_idx + i * cols + j,
+                            x + (max_glyph_width + 1) * j - x0,
+                            y + (max_glyph_height + 1) * i - y0);
+             }
        }
       update_mask = 0;
     }