/uppbox/FontMaps2/TypeReader.cpp

https://github.com/ultimatepp/ultimatepp · C++ · 235 lines · 201 code · 19 blank · 15 comment · 55 complexity · 8f4346846a7018d2ef26e138f6bb2a65 MD5 · raw file

  1. #include "TypeReader.h"
  2. #define LLOG(x) // LOG(x)
  3. #define LDUMP(x) // LLOG(#x << " = " << x);
  4. int FontTypeReader::Peek8(const char *s)
  5. {
  6. return s + 1 < font.end() ? (byte)*s : Error();
  7. }
  8. int FontTypeReader::Peek16(const char *s)
  9. {
  10. return s + 2 < font.end() ? Peek16be(s) : Error();
  11. }
  12. int FontTypeReader::Peek32(const char *s)
  13. {
  14. return s + 4 < font.end() ? Peek32be(s) : Error();
  15. }
  16. int FontTypeReader::Peek8(const char *s, int i)
  17. {
  18. return Peek8(s + i);
  19. }
  20. int FontTypeReader::Peek16(const char *s, int i)
  21. {
  22. return Peek16(s + 2 * i);
  23. }
  24. int FontTypeReader::Peek32(const char *s, int i)
  25. {
  26. return Peek32(s + 4 * i);
  27. }
  28. int FontTypeReader::Read8(const char *&s)
  29. {
  30. int q = byte(*s);
  31. s++;
  32. return q;
  33. }
  34. int FontTypeReader::Read16(const char *&s)
  35. {
  36. int q = Peek16(s);
  37. s += 2;
  38. return q;
  39. }
  40. int FontTypeReader::Read32(const char *&s)
  41. {
  42. int q = Peek32(s);
  43. s += 4;
  44. return q;
  45. }
  46. const char *FontTypeReader::Seek(const char *tab, int& len)
  47. {
  48. ASSERT(strlen(tab) == 4);
  49. int q = table.Find(tab);
  50. if(q < 0)
  51. Error();
  52. len = table[q].length;
  53. return ~font + table[q].offset;
  54. }
  55. const char *FontTypeReader::Seek(const char *tab)
  56. {
  57. int dummy;
  58. return Seek(tab, dummy);
  59. }
  60. bool FontTypeReader::Open(const String& fnt, bool symbol, bool justcheck)
  61. {
  62. // DDUMP(fnt.GetCount());
  63. try {
  64. int i;
  65. table.Clear();
  66. font = fnt;
  67. const char *s = fnt;
  68. int q = Read32(s);
  69. if(q != 0x74727565 && q != 0x00010000)
  70. Error();
  71. int n = Read16(s);
  72. s += 6;
  73. while(n--) {
  74. // DDUMP(String(s, 4));
  75. Table& t = table.Add(String(s, 4));
  76. s += 8; // skip checksum
  77. t.offset = Read32(s);
  78. // DDUMP(t.offset);
  79. t.length = Read32(s);
  80. // DDUMP(t.length);
  81. // DLOG("----");
  82. }
  83. #if 0
  84. for(i = 0; i < table.GetCount(); i++)
  85. LLOG("table: " << table.GetKey(i) << " offset: " << table[i].offset << " length: " << table[i].length);
  86. s = Seek("hmtx");
  87. int aw = 0;
  88. for(i = 0; i < hhea.numOfLongHorMetrics; i++) {
  89. aw = glyphinfo[i].advanceWidth = (uint16)Read16(s);
  90. glyphinfo[i].leftSideBearing = (int16)Read16(s);
  91. }
  92. for(; i < maxp.numGlyphs; i++) {
  93. glyphinfo[i].advanceWidth = aw;
  94. glyphinfo[i].leftSideBearing = (int16)Read16(s);
  95. }
  96. s = Seek("loca");
  97. for(i = 0; i < maxp.numGlyphs; i++)
  98. if(head.indexToLocFormat) {
  99. glyphinfo[i].offset = Peek32(s, i);
  100. glyphinfo[i].size = Peek32(s, i + 1) - glyphinfo[i].offset;
  101. }
  102. else {
  103. glyphinfo[i].offset = 2 * (word)Peek16(s, i);
  104. glyphinfo[i].size = 2 * (word)Peek16(s, i + 1) - glyphinfo[i].offset;
  105. }
  106. for(i = 0; i < maxp.numGlyphs; i++)
  107. LLOG(i << " advance: " << glyphinfo[i].advanceWidth << ", left: " << glyphinfo[i].leftSideBearing
  108. << ", offset: " << glyphinfo[i].offset << ", size: " << glyphinfo[i].size);
  109. #endif
  110. bool found = false;
  111. for(int pass = 0; pass < 2; pass++) {
  112. const char *s = Seek("cmap");
  113. const char *p = s;
  114. // LOGHEXDUMP(p, 256);
  115. p += 2;
  116. n = Read16(p);
  117. // DDUMP(n);
  118. while(n--) {
  119. int pid = Read16(p);
  120. int psid = Read16(p);
  121. int offset = Read32(p);
  122. if(offset < 0 || offset > font.GetLength())
  123. Error();
  124. int format = Peek16(s + offset);
  125. LLOG("cmap pid: " << pid << " psid: " << psid << " format: " << format);
  126. //Test with Symbol font !!!; improve - Unicode first, 256 bytes later..., symbol...
  127. if(symbol) {
  128. if(pid == 1 && psid == 0 && Peek16(s + offset) == 0) {
  129. LLOG("Reading symbol table");
  130. p = s + offset + 6;
  131. for(int i = 0; i < 256; i++);
  132. //SetGlyph(i, (byte)p[i]);
  133. goto done;
  134. }
  135. }
  136. else
  137. if(pid == 3 && psid == 10 && format == 12 && pass == 0) {
  138. const char *p = s + offset;
  139. int ngroups = Peek32(p + 12);
  140. p += 16; // pointer to groups table
  141. for(int i = 0; i < ngroups; i++) {
  142. LLOG(Peek32(p) << " - " << Peek32(p + 4) << ", glyphi: " << Peek32(p + 8));
  143. ranges.Add(MakeTuple(Peek32(p), Peek32(p + 4)));
  144. p += 12;
  145. }
  146. goto done;
  147. }
  148. else
  149. if(pid == 3 && psid == 1 && format == 4 && pass == 1) {
  150. const char *p = s + offset;
  151. int n = Peek16(p + 6) >> 1;
  152. LLOG("Found UNICODE encoding, offset " << offset << ", segments " << n);
  153. const char *seg_end = p + 14;
  154. const char *seg_start = seg_end + 2 * n + 2;
  155. const char *idDelta = seg_start + 2 * n;
  156. const char *idRangeOffset = idDelta + 2 * n;
  157. for(int i = 0; i < n; i++) {
  158. int start = Peek16(seg_start, i);
  159. int end = Peek16(seg_end, i);
  160. ranges.Add(MakeTuple(start, end));
  161. #if 0
  162. int delta = Peek16(idDelta, i);
  163. int ro = Peek16(idRangeOffset, i);
  164. if (ro && delta == 0) {
  165. LOG(start << " - " << end);
  166. LLOG("RangeOffset start: " << start << ", end: " << end << ", delta: " << (int16)delta);
  167. LLOG("ro " << ro);
  168. // const char *q = idRangeOffset + 2 * i + ro;
  169. // for(int c = start; c <= end; c++) {
  170. // SetGlyph(c, (word)Read16(q));
  171. // }
  172. }
  173. else {
  174. LOG(start << " - " << end);
  175. LLOG("Delta start: " << start << ", end: " << end << ", delta: " << (int16)delta);
  176. // for(int c = start; c <= end; c++);
  177. // SetGlyph(c, c + delta);
  178. }
  179. #endif
  180. }
  181. break;
  182. }
  183. }
  184. }
  185. done:
  186. int len;
  187. const char *strings = Seek("name", len);
  188. s = strings + 2;
  189. int count = Read16(s);
  190. strings += (word)Read16(s);
  191. for(int i = 0; i < count; i++) {
  192. int platform = Read16(s);
  193. s += 4;
  194. if(Read16(s) == 6) {
  195. int len = Read16(s);
  196. int offset = Read16(s);
  197. if(platform == 1)
  198. ps_name = String(strings + offset, len);
  199. else {
  200. s = strings + offset;
  201. len >>= 1;
  202. while(len--)
  203. ps_name.Cat(Read16(s));
  204. }
  205. break;
  206. }
  207. s += 4;
  208. }
  209. DDUMP(ps_name);
  210. }
  211. catch(Fail) {
  212. DLOG("ERROR");
  213. return false;
  214. }
  215. return true;
  216. }