1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/graphite2/src/gr_logging.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,242 @@ 1.4 +/* GRAPHITE2 LICENSING 1.5 + 1.6 + Copyright 2010, SIL International 1.7 + All rights reserved. 1.8 + 1.9 + This library is free software; you can redistribute it and/or modify 1.10 + it under the terms of the GNU Lesser General Public License as published 1.11 + by the Free Software Foundation; either version 2.1 of License, or 1.12 + (at your option) any later version. 1.13 + 1.14 + This program is distributed in the hope that it will be useful, 1.15 + but WITHOUT ANY WARRANTY; without even the implied warranty of 1.16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1.17 + Lesser General Public License for more details. 1.18 + 1.19 + You should also have received a copy of the GNU Lesser General Public 1.20 + License along with this library in the file named "LICENSE". 1.21 + If not, write to the Free Software Foundation, 51 Franklin Street, 1.22 + Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 1.23 + internet at http://www.fsf.org/licenses/lgpl.html. 1.24 + 1.25 +Alternatively, the contents of this file may be used under the terms of the 1.26 +Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public 1.27 +License, as published by the Free Software Foundation, either version 2 1.28 +of the License or (at your option) any later version. 1.29 +*/ 1.30 +#include <stdio.h> 1.31 + 1.32 +#include "graphite2/Log.h" 1.33 +#include "inc/debug.h" 1.34 +#include "inc/CharInfo.h" 1.35 +#include "inc/Slot.h" 1.36 +#include "inc/Segment.h" 1.37 +#include "inc/json.h" 1.38 + 1.39 +#if defined _WIN32 1.40 +#include "windows.h" 1.41 +#endif 1.42 + 1.43 +using namespace graphite2; 1.44 + 1.45 +#if !defined GRAPHITE2_NTRACING 1.46 +json *global_log = NULL; 1.47 +#endif 1.48 + 1.49 +extern "C" { 1.50 + 1.51 +bool gr_start_logging(GR_MAYBE_UNUSED gr_face * face, const char *log_path) 1.52 +{ 1.53 + if (!log_path) return false; 1.54 + 1.55 +#if !defined GRAPHITE2_NTRACING 1.56 + gr_stop_logging(face); 1.57 +#if defined _WIN32 1.58 + int n = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, log_path, -1, 0, 0); 1.59 + if (n == 0 || n > MAX_PATH - 12) return false; 1.60 + 1.61 + LPWSTR wlog_path = gralloc<WCHAR>(n); 1.62 + if (!wlog_path) return false; 1.63 + FILE *log = 0; 1.64 + if (wlog_path && MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, log_path, -1, wlog_path, n)) 1.65 + log = _wfopen(wlog_path, L"wt"); 1.66 + 1.67 + free(wlog_path); 1.68 +#else // _WIN32 1.69 + FILE *log = fopen(log_path, "wt"); 1.70 +#endif // _WIN32 1.71 + if (!log) return false; 1.72 + 1.73 + if (face) 1.74 + { 1.75 + face->setLogger(log); 1.76 + if (!face->logger()) return false; 1.77 + 1.78 + *face->logger() << json::array; 1.79 +#ifdef GRAPHITE2_TELEMETRY 1.80 + *face->logger() << face->tele; 1.81 +#endif 1.82 + } 1.83 + else 1.84 + { 1.85 + global_log = new json(log); 1.86 + *global_log << json::array; 1.87 + } 1.88 + 1.89 + return true; 1.90 +#else // GRAPHITE2_NTRACING 1.91 + return false; 1.92 +#endif // GRAPHITE2_NTRACING 1.93 +} 1.94 + 1.95 +bool graphite_start_logging(FILE * /* log */, GrLogMask /* mask */) 1.96 +{ 1.97 +//#if !defined GRAPHITE2_NTRACING 1.98 +// graphite_stop_logging(); 1.99 +// 1.100 +// if (!log) return false; 1.101 +// 1.102 +// dbgout = new json(log); 1.103 +// if (!dbgout) return false; 1.104 +// 1.105 +// *dbgout << json::array; 1.106 +// return true; 1.107 +//#else 1.108 + return false; 1.109 +//#endif 1.110 +} 1.111 + 1.112 +void gr_stop_logging(GR_MAYBE_UNUSED gr_face * face) 1.113 +{ 1.114 +#if !defined GRAPHITE2_NTRACING 1.115 + if (face && face->logger()) 1.116 + { 1.117 + FILE * log = face->logger()->stream(); 1.118 + face->setLogger(0); 1.119 + fclose(log); 1.120 + } 1.121 + else if (!face && global_log) 1.122 + { 1.123 + FILE * log = global_log->stream(); 1.124 + delete global_log; 1.125 + fclose(log); 1.126 + } 1.127 +#endif 1.128 +} 1.129 + 1.130 +void graphite_stop_logging() 1.131 +{ 1.132 +// if (dbgout) delete dbgout; 1.133 +// dbgout = 0; 1.134 +} 1.135 + 1.136 +} // extern "C" 1.137 + 1.138 +#ifdef GRAPHITE2_TELEMETRY 1.139 +size_t * graphite2::telemetry::_category = 0UL; 1.140 +#endif 1.141 + 1.142 +#if !defined GRAPHITE2_NTRACING 1.143 + 1.144 +#ifdef GRAPHITE2_TELEMETRY 1.145 + 1.146 +json & graphite2::operator << (json & j, const telemetry & t) throw() 1.147 +{ 1.148 + j << json::object 1.149 + << "type" << "telemetry" 1.150 + << "silf" << t.silf 1.151 + << "states" << t.states 1.152 + << "starts" << t.starts 1.153 + << "transitions" << t.transitions 1.154 + << "glyphs" << t.glyph 1.155 + << "code" << t.code 1.156 + << "misc" << t.misc 1.157 + << "total" << (t.silf + t.states + t.starts + t.transitions + t.glyph + t.code + t.misc) 1.158 + << json::close; 1.159 + return j; 1.160 +} 1.161 +#else 1.162 +json & graphite2::operator << (json & j, const telemetry &) throw() 1.163 +{ 1.164 + return j; 1.165 +} 1.166 +#endif 1.167 + 1.168 + 1.169 +json & graphite2::operator << (json & j, const CharInfo & ci) throw() 1.170 +{ 1.171 + return j << json::object 1.172 + << "offset" << ci.base() 1.173 + << "unicode" << ci.unicodeChar() 1.174 + << "break" << ci.breakWeight() 1.175 + << "flags" << ci.flags() 1.176 + << "slot" << json::flat << json::object 1.177 + << "before" << ci.before() 1.178 + << "after" << ci.after() 1.179 + << json::close 1.180 + << json::close; 1.181 +} 1.182 + 1.183 + 1.184 +json & graphite2::operator << (json & j, const dslot & ds) throw() 1.185 +{ 1.186 + assert(ds.first); 1.187 + assert(ds.second); 1.188 + const Segment & seg = *ds.first; 1.189 + const Slot & s = *ds.second; 1.190 + 1.191 + j << json::object 1.192 + << "id" << objectid(ds) 1.193 + << "gid" << s.gid() 1.194 + << "charinfo" << json::flat << json::object 1.195 + << "original" << s.original() 1.196 + << "before" << s.before() 1.197 + << "after" << s.after() 1.198 + << json::close 1.199 + << "origin" << s.origin() 1.200 + << "shift" << Position(float(s.getAttr(0, gr_slatShiftX, 0)), 1.201 + float(s.getAttr(0, gr_slatShiftY, 0))) 1.202 + << "advance" << s.advancePos() 1.203 + << "insert" << s.isInsertBefore() 1.204 + << "break" << s.getAttr(&seg, gr_slatBreak, 0); 1.205 + if (s.just() > 0) 1.206 + j << "justification" << s.just(); 1.207 + if (s.getBidiLevel() > 0) 1.208 + j << "bidi" << s.getBidiLevel(); 1.209 + if (!s.isBase()) 1.210 + j << "parent" << json::flat << json::object 1.211 + << "id" << objectid(dslot(&seg, s.attachedTo())) 1.212 + << "level" << s.getAttr(0, gr_slatAttLevel, 0) 1.213 + << "offset" << s.attachOffset() 1.214 + << json::close; 1.215 + j << "user" << json::flat << json::array; 1.216 + for (int n = 0; n!= seg.numAttrs(); ++n) 1.217 + j << s.userAttrs()[n]; 1.218 + j << json::close; 1.219 + if (s.firstChild()) 1.220 + { 1.221 + j << "children" << json::flat << json::array; 1.222 + for (const Slot *c = s.firstChild(); c; c = c->nextSibling()) 1.223 + j << objectid(dslot(&seg, c)); 1.224 + j << json::close; 1.225 + } 1.226 + return j << json::close; 1.227 +} 1.228 + 1.229 + 1.230 +graphite2::objectid::objectid(const dslot & ds) throw() 1.231 +{ 1.232 + const Slot * const p = ds.second; 1.233 + uint32 s = reinterpret_cast<size_t>(p); 1.234 + sprintf(name, "%.4x-%.2x-%.4hx", uint16(s >> 16), uint16(p ? p->userAttrs()[ds.first->silf()->numUser()] : 0), uint16(s)); 1.235 + name[sizeof name-1] = 0; 1.236 +} 1.237 + 1.238 +graphite2::objectid::objectid(const Segment * const p) throw() 1.239 +{ 1.240 + uint32 s = reinterpret_cast<size_t>(p); 1.241 + sprintf(name, "%.4x-%.2x-%.4hx", uint16(s >> 16), 0, uint16(s)); 1.242 + name[sizeof name-1] = 0; 1.243 +} 1.244 + 1.245 +#endif