[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Groff] unicode support, part 6 X: public glyph to name/number API
From: |
Bruno Haible |
Subject: |
[Groff] unicode support, part 6 X: public glyph to name/number API |
Date: |
Wed, 15 Feb 2006 13:21:44 +0100 |
User-agent: |
KMail/1.5 |
Hi,
The logical consequence of the last patch that added glyph::glyph_name(),
needed for unicode fonts, is the reverse mapping from glyph to index or
number.
Please don't apply this patch! It is too ugly to have to convert a string
from decimal to binary in order to find the number to which a glyph is
defined. This patch shows that some more simplification of the two 'glyph'
implementations are needed first.
diff -r -u groff-20060213.orig/src/include/font.h
groff-20060213/src/include/font.h
--- groff-20060213.orig/src/include/font.h 2006-02-13 13:00:19.000000000
+0100
+++ groff-20060213/src/include/font.h 2006-02-14 02:36:22.000000000 +0100
@@ -227,7 +227,7 @@
// device) and initialize some static variables with
// info from there.
- // The next two functions exist in two versions: one in
+ // The next four functions exist in two versions: one in
// roff/troff/input.cpp for troff, and one for
// libs/libgroff/nametoindex.cpp for the preprocessors and the
// postprocessors.
@@ -241,6 +241,12 @@
// object. This has the same semantics as the groff
// escape sequence \N'number'. If such a `glyph'
// object does not yet exist, a new one is allocated.
+ static const char *index_to_name(glyph); // Convert the given glyph
+ // back to its name. Return NULL if the glyph
+ // doesn't have a name.
+ static int index_to_number(glyph); // Convert the given glyph back to
+ // its number. Return -1 if it does not designate
+ // a numbered character.
static FONT_COMMAND_HANDLER
set_unknown_desc_command_handler(FONT_COMMAND_HANDLER); // Register
diff -r -u groff-20060213.orig/src/libs/libgroff/nametoindex.cpp
groff-20060213/src/libs/libgroff/nametoindex.cpp
--- groff-20060213.orig/src/libs/libgroff/nametoindex.cpp 2006-02-13
13:00:19.000000000 +0100
+++ groff-20060213/src/libs/libgroff/nametoindex.cpp 2006-02-14
02:40:28.000000000 +0100
@@ -36,15 +36,26 @@
public:
character_indexer();
~character_indexer();
+ // --------------------- Lookup or creation of a glyph.
glyph ascii_char_index(unsigned char);
glyph named_char_index(const char *);
glyph numbered_char_index(int);
+ // --------------------- Retrieve information about a glyph.
+ int index_as_ascii_char(glyph); // Return the 'unsigned char' value,
+ // or -1 if not a single-char glyph.
+ int index_as_numbered_char(glyph); // Return the numbered glyph value,
+ // or -1 if not a numbered glyph.
+ const char *index_to_name(glyph); // Return the glyph name, or NULL
+ // if not a named glyph.
private:
+ int next_index; // Number of glyphs already allocated.
+ PTABLE(int) table; // Table mapping name to glyph. For numbered glyphs,
+ // " NNNN" is used as a name in the table.
+ glyph ascii_index[256]; // Shorthand table for looking up "charNNN"
+ // glyphs.
enum { NSMALL = 256 };
- int next_index;
- glyph ascii_index[256];
- glyph small_number_index[NSMALL];
- PTABLE(int) table;
+ glyph small_number_index[NSMALL]; // Shorthand table for looking up
+ // numbered glyphs.
};
character_indexer::character_indexer()
@@ -75,21 +86,26 @@
glyph character_indexer::numbered_char_index(int n)
{
if (n >= 0 && n < NSMALL) {
- if (small_number_index[n].index < 0)
- small_number_index[n] = glyph(next_index++, NULL);
+ if (small_number_index[n].index < 0) {
+ char buf[1 + 1 + INT_DIGITS + 1];
+ buf[0] = ' ';
+ strcpy(buf + 1, i_to_a(n));
+ small_number_index[n] = glyph(next_index++, strsave(buf));
+ }
return small_number_index[n];
}
// Not the most efficient possible implementation.
char buf[1 + 1 + INT_DIGITS + 1];
buf[0] = ' ';
strcpy(buf + 1, i_to_a(n));
- int *np = table.lookup(buf);
+ const char *s = buf;
+ int *np = table.lookupassoc(&s);
if (!np) {
np = new int[1];
*np = next_index++;
- table.define(buf, np);
+ s = table.define(s, np);
}
- return glyph(*np, NULL);
+ return glyph(*np, s);
}
glyph character_indexer::named_char_index(const char *s)
@@ -103,6 +119,56 @@
return glyph(*np, s);
}
+int character_indexer::index_as_ascii_char(glyph g)
+{
+ if (g.index >= 0 && g.index < next_index) {
+ const char *name = g.name;
+ if (name != NULL)
+ if (name[0] == 'c' && name[1] == 'h' && name[2] == 'a' && name[3] == 'r'
+ && (name[4] >= '0' && name[4] <= '9')) {
+ int n = (name[4] - '0');
+ if (name[5] == '\0')
+ return n;
+ if (n > 0 && (name[5] >= '0' && name[5] <= '9')) {
+ n = 10*n + (name[5] - '0');
+ if (name[6] == '\0')
+ return n;
+ if (name[6] >= '0' && name[6] <= '9') {
+ n = 10*n + (name[6] - '0');
+ if (name[7] == '\0' && n < 256)
+ return n;
+ }
+ }
+ }
+ }
+ return -1;
+}
+
+int character_indexer::index_as_numbered_char(glyph g)
+{
+ if (g.index >= 0 && g.index < next_index) {
+ const char *name = g.name;
+ if (name != NULL)
+ if (name[0] == ' ' && (name[1] >= '0' && name[1] <= '9')) {
+ char *end;
+ long n = strtol(name + 1, &end, 10);
+ if (end > name + 1 && *end == '\0' && n == (int)n)
+ return (int)n;
+ }
+ }
+ return -1;
+}
+
+const char *character_indexer::index_to_name(glyph g)
+{
+ if (g.index >= 0 && g.index < next_index) {
+ const char *name = g.name;
+ if (name != NULL && name[0] != ' ')
+ return name;
+ }
+ return NULL;
+}
+
static character_indexer indexer;
glyph font::number_to_index(int n)
@@ -124,3 +190,13 @@
}
return glyph(indexer.named_char_index(s));
}
+
+const char *font::index_to_name(glyph g)
+{
+ return indexer.index_to_name(g);
+}
+
+int font::index_to_number(glyph g)
+{
+ return indexer.index_as_numbered_char(g);
+}
diff -r -u groff-20060213.orig/src/roff/troff/input.cpp
groff-20060213/src/roff/troff/input.cpp
--- groff-20060213.orig/src/roff/troff/input.cpp 2006-02-13
13:00:20.000000000 +0100
+++ groff-20060213/src/roff/troff/input.cpp 2006-02-14 02:41:59.000000000
+0100
@@ -8162,8 +8162,6 @@
return number;
}
-symbol UNNAMED_SYMBOL("---");
-
// For numbered characters not between 0 and 255, we make a symbol out
// of the number and store them in this dictionary.
@@ -8176,7 +8174,10 @@
if (n >= 0 && n < 256) {
charinfo *ci = number_table[n];
if (!ci) {
- ci = new charinfo(UNNAMED_SYMBOL);
+ char buf[1 + 1 + INT_DIGITS + 1];
+ buf[0] = ' ';
+ strcpy(buf + 1, i_to_a(n));
+ ci = new charinfo(symbol(buf));
ci->set_number(n);
number_table[n] = ci;
}
@@ -8186,7 +8187,10 @@
symbol ns(i_to_a(n));
charinfo *ci = (charinfo *)numbered_charinfo_dictionary.lookup(ns);
if (!ci) {
- ci = new charinfo(UNNAMED_SYMBOL);
+ char buf[1 + 1 + INT_DIGITS + 1];
+ buf[0] = ' ';
+ strcpy(buf + 1, i_to_a(n));
+ ci = new charinfo(symbol(buf));
ci->set_number(n);
(void)numbered_charinfo_dictionary.lookup(ns, ci);
}
@@ -8213,3 +8217,23 @@
{
return get_charinfo_by_number(n)->get_index();
}
+
+const char *font::index_to_name(glyph g)
+{
+ const char *name = g.name;
+ if (name[0] != ' ')
+ return name;
+ return NULL;
+}
+
+int font::index_to_number(glyph g)
+{
+ const char *name = g.name;
+ if (name[0] == ' ' && (name[1] >= '0' && name[1] <= '9')) {
+ char *end;
+ long n = strtol(name + 1, &end, 10);
+ if (end > name + 1 && *end == '\0' && n == (int)n)
+ return (int)n;
+ }
+ return -1;
+}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Groff] unicode support, part 6 X: public glyph to name/number API,
Bruno Haible <=