dstyle.cc
来自「Click is a modular router toolkit. To us」· CC 代码 · 共 2,157 行 · 第 1/4 页
CC
2,157 行
#ifdef HAVE_CONFIG_H# include <config.h>#endif#include <click/config.h>#include "dstyle.hh"#include "dwidget.hh"#include "wdiagram.hh"#include "hvalues.hh"#include <click/userutils.hh>#include <click/confparse.hh>#include <click/straccum.hh>#include <click/bitvector.hh>#include <clicktool/processingt.hh>#include <clicktool/elementmap.hh>#include <list>#include <math.h>#include <string.h>#include "crouter.hh"#include "whandler.hh"extern "C" {#include "support.h"}namespace clicky {struct colordef { const char *name; int length; uint32_t value;};static const colordef colordefs[] = { { "aqua", 4, 0x00FFFF }, { "black", 5, 0x000000 }, { "blue", 4, 0x0000FF }, { "fuchsia", 7, 0xFF00FF }, { "gray", 4, 0x808080 }, { "green", 5, 0x008000 }, { "lime", 4, 0x00FF00 }, { "maroon", 6, 0x800000 }, { "navy", 4, 0x000080 }, { "none", 4, 0xFF000000 }, { "olive", 5, 0x808000 }, { "orange", 6, 0xFFA500 }, { "purple", 6, 0x800080 }, { "red", 3, 0xFF0000 }, { "silver", 6, 0xC0C0C0 }, { "teal", 4, 0x008080 }, { "white", 5, 0xFFFFFF }, { "yellow", 6, 0xFFFF00 }};const double white_color[4] = { 1, 1, 1, 1 };const char default_css[] = "port.input {\n\ port-shape: triangle;\n\ port-length: 11px;\n\ port-width: 7px;\n\ port-margin: 1px;\n\ port-edge-padding: 2px;\n\}\n\port.output {\n\ port-shape: rectangle;\n\ port-length: 9px;\n\ port-width: 5.5px;\n\ port-margin: 1px;\n\ port-edge-padding: 2px;\n\}\n\port.push, port.push.agnostic {\n\ port-color: black;\n\}\n\port.pull, port.pull.agnostic {\n\ port-color: white;\n\}\n\port.agnostic {\n\ port-color: gray;\n\}\n\port.push, port.pull {\n\ port-border: black 1px solid;\n\}\n\port.agnostic, port.push.agnostic, port.pull.agnostic {\n\ port-border: black 1px inset;\n\}\n\port.push.error, port.push.agnostic.error {\n\ port-color: red;\n\}\n\port.pull.error, port.pull.agnostic.error {\n\ port-color: rgb(100%, 75%, 75%);\n\}\n\port.push.error, port.pull.error {\n\ port-border: red 1px solid;\n\}\n\port.agnostic.error, port.push.agnostic.error, port.pull.agnostic.error {\n\ port-border: red 1px inset;\n\}\n\* {\n\ background: rgb(100%, 100%, 87%);\n\ color: black;\n\ border: 1px solid black;\n\ padding: 8px 12px;\n\ margin: 20px 14px;\n\ shadow: drop rgba(50%, 50%, 45%, 50%) 3px;\n\ orientation: vertical;\n\ /* min-height: 30px; */\n\ /* height-step: 4px; */\n\ scale: 100%;\n\ queue-stripe: 1px solid rgb(87%, 87%, 50%);\n\ queue-stripe-spacing: 12px;\n\ text: \"%n\\n<small>%c</small>\";\n\ display: open;\n\ port-display: both;\n\ port-font: 6;\n\ @media print {\n\ font: Times;\n\ port-font: Times 6;\n\ }\n\ /* @media screen { font: URW Palladio L italic 20; } */\n\}\n\*.anonymous {\n\ text: \"%n\";\n\}\n\* * {\n\ background: rgb(98%, 98%, 81%);\n\}\n\* * * {\n\ background: rgb(96%, 96%, 75%);\n\}\n\* * * * {\n\ background: rgb(94%, 94%, 69%);\n\}\n\@media screen {\n\*:hover {\n\ background: #fffff2;\n\}\n\*:active, *:active:hover {\n\ background: #ffff94;\n\ shadow: unscaled-outline rgba(90%, 20%, 95%, 50%) 3px;\n\}\n\*:pressed, *:active:pressed {\n\ shadow: drop rgba(50%, 50%, 45%, 50%) 3px;\n\}\n\}\n\*Queue {\n\ min-length: 49.6px;\n\ style: queue;\n\}\n\fullness {\n\ style: fullness;\n\ length: length;\n\ capacity: capacity;\n\ color: rgba(0%, 0%, 100%, 20%);\n\ autorefresh: length 0.1s;\n\}\n\activity {\n\ style: activity;\n\ handler: count;\n\ decay: 5s;\n\ max-value: 3;\n\ type: rate;\n\ autorefresh: 1s;\n\}";/***** * property definitions */static PermString::Initializer permstring_initializer;static HashTable<PermString, int> property_map;static dcss_propmatch port_pm[] = { { "port-shape", 0 }, { "port-length", 0 }, { "port-width", 0 }, { "port-color", 0 }, { "port-border-style", 0 }, { "port-border-width", 0 }, { "port-border-color", 0 }, { "port-margin-top", 0 }, { "port-margin-right", 0 }, { "port-margin-bottom", 0 }, { "port-margin-left", 0 }, { "port-edge-padding", 0 }, { "port-display", 0 }, { "port-text", 0 }, { "port-font", 0 }};static dcss_propmatch elt_pm[] = { { "color", 0 }, { "background-color", 0 }, { "border-style", 0 }, { "border-color", 0 }, { "shadow-style", 0 }, { "shadow-width", 0 }, { "shadow-color", 0 }, { "style", 0 }, { "text", 0 }, { "display", 0 }, { "font", 0 }, { "decorations", 0 }, { "queue-stripe-style", 0 }, { "queue-stripe-width", 0 }, { "queue-stripe-color", 0 }, { "port-split", 0 }, { "flow-split", 0 }};static dcss_propmatch elt_size_pm[] = { { "border-width", 0 }, { "padding-top", 0 }, { "padding-right", 0 }, { "padding-bottom", 0 }, { "padding-left", 0 }, { "min-width", 0 }, { "min-height", 0 }, { "height-step", 0 }, { "margin-top", 0 }, { "margin-right", 0 }, { "margin-bottom", 0 }, { "margin-left", 0 }, { "queue-stripe-spacing", 0 }, { "scale", 0 }, { "orientation", 0 }, { "min-length", 0 }};static dcss_propmatch handler_pm[] = { { "autorefresh", 0 }, { "autorefresh-period", 0 }, { "display", 0 }, { "allow-refresh", 0 }};static dcss_propmatch fullness_pm[] = { { "length", 0 }, { "capacity", 0 }, { "color", 0 }, { "autorefresh", 0 }, { "autorefresh-period", 0 }};static dcss_propmatch activity_pm[] = { { "handler", 0 }, { "color", 0 }, { "autorefresh", 0 }, { "autorefresh-period", 0 }, { "type", 0 }, { "max-value", 0 }, { "min-value", 0 }, { "decay", 0 }};enum { num_port_pm = sizeof(port_pm) / sizeof(port_pm[0]), pflag_port = 1, num_elt_pm = sizeof(elt_pm) / sizeof(elt_pm[0]), pflag_elt = 2, num_elt_size_pm = sizeof(elt_size_pm) / sizeof(elt_size_pm[0]), pflag_elt_size = 4, num_handler_pm = sizeof(handler_pm) / sizeof(handler_pm[0]), pflag_handler = 8, num_fullness_pm = sizeof(fullness_pm) / sizeof(fullness_pm[0]), pflag_fullness = 16, num_activity_pm = sizeof(activity_pm) / sizeof(activity_pm[0]), pflag_activity = 32, pflag_no_below = 64};/***** * */bool cp_pixel(const String &str, double *v){ double scale = 1; const char *s = str.begin(), *send = str.end(); if (s + 2 < send) { if (send[-2] == 'p' && send[-1] == 'x') send -= 2; else if (send[-2] == 'i' && send[-1] == 'n') scale = 96, send -= 2; else if (send[-2] == 'c' && send[-1] == 'm') scale = 96.0 / 2.54, send -= 2; else if (send[-2] == 'm' && send[-1] == 'm') scale = 96.0 / 25.4, send -= 2; else if (send[-2] == 'p' && send[-1] == 't') scale = 96.0 / 72.0, send -= 2; else if (send[-2] == 'p' && send[-1] == 'c') scale = 96.0 / 6.0, send -= 2; /* XXX em, ex? */ } double value; if (cp_double(str.substring(s, send), &value)) { *v = value * scale; return true; } else return false;}bool cp_relative(const String &str, double *v){ if (str && str.back() == '%' && cp_double(str.substring(0, -1), v)) { *v /= 100; return true; } else return cp_double(str, v);}bool cp_color(const String &str, double *r, double *g, double *b, double *a){ const char *s = str.begin(), *send = str.end(); if (s == send || (s[0] == '#' && s + 4 != send && s + 7 != send)) return false; // hex specification? if (s[0] == '#') { uint32_t v = 0; for (++s; s != send; ++s) if (*s >= '0' && *s <= '9') v = (v << 4) + *s - '0'; else if (*s >= 'A' && *s <= 'F') v = (v << 4) + *s - 'A' + 10; else if (*s >= 'a' && *s <= 'f') v = (v << 4) + *s - 'a' + 10; else return false; if (str.length() == 4) { *r = (v >> 8) / 15.; *g = ((v >> 4) & 0xF) / 15.; *b = (v & 0xF) / 15.; if (a) *a = 1; return true; } else { *r = (v >> 16) / 255.; *g = ((v >> 8) & 0xFF) / 255.; *b = (v & 0xFF) / 255.; if (a) *a = 1; return true; } } // rgb specification? if (s + 5 < send && (memcmp(s, "rgb(", 4) == 0 || memcmp(s, "rgba(", 5) == 0)) { double x[4]; if (s[3] == 'a') ++s; s += 4; x[3] = 1; for (int i = 0; i < 4; ++i) { s = cp_skip_comment_space(s, send); const char *n = s; while (s != send && (isdigit((unsigned char) *s) || *s == '.' || *s == '+' || *s == '-')) ++s; if (s == send || n == s) return false; x[i] = strtod(n, 0); if (*s == '%') { x[i] /= 100.; ++s; } else if (i < 3) x[i] /= 255.; if (x[i] < 0) x[i] = 0; else if (x[i] > 1) x[i] = 1; if (i < 3) { if (s != send && *s != ',') s = cp_skip_comment_space(s, send); if (s != send && *s == ')' && i >= 2) break; else if (s != send && *s == ',') ++s; else if (s != send) return false; } } s = cp_skip_comment_space(s, send); if (s + 1 != send || s[0] != ')') return false; *r = x[0]; *g = x[1]; *b = x[2]; if (a) *a = x[3]; return true; } // color name? const colordef *cl = colordefs; const colordef *cr = colordefs + sizeof(colordefs) / sizeof(colordefs[0]); while (cl < cr) { const colordef *cm = cl + (cr - cl) / 2; if (*s == cm->name[0] && s + cm->length == send && memcmp(s, cm->name, cm->length) == 0) { *r = ((cm->value >> 16) & 0xFF) / 255.; *g = ((cm->value >> 8) & 0xFF) / 255.; *b = (cm->value & 0xFF) / 255.; if (a) *a = (255 - (cm->value >> 24)) / 255.; return true; } int cmp; if (*s < cm->name[0]) cmp = -1; else if (*s > cm->name[0]) cmp = 1; else { int len = (send - s < cm->length ? send - s : cm->length); if (!(cmp = memcmp(s, cm->name, len))) cmp = (cm->length == len ? 1 : -1); } if (cmp < 0) cr = cm; else cl = cm + 1; } return false;}static const char *ccss_skip_braces(const char *s, const char *send, bool one_word = false){ int nopen = 0; for (; s != send; ++s) if (*s == '/' && s + 1 != send && (s[1] == '/' || s[1] == '*')) s = cp_skip_comment_space(s, send) - 1; else if (*s == '\"' || *s == '\'') { char quote = *s; for (++s; s != send && *s != quote; ++s) if (*s == '\\') { if (s + 2 < send && s[1] == '\r' && s[2] == '\n') s += 2; else if (s + 1 != send) ++s; } else if (*s == '\n' || *s == '\r' || *s == '\f') break; if (s == send) break; if (one_word && !nopen) { ++s; break; } } else if (*s == '}' && --nopen < 0) return s + 1; else if (*s == '{') ++nopen; else if (one_word && (isspace((unsigned char) *s) || *s == ';')) break; return s;}static String ccss_pop_commavec(String &str){ const char *s = str.begin(), *send = str.end(); int parens = 0, quotes = 0; const char *sarg = cp_skip_comment_space(s, send); const char *last_nonsp = sarg - 1; for (; s != send; ++s) { if (*s == ',' && !parens && !quotes) break; if (!isspace((unsigned char) *s)) last_nonsp = s; if (*s == '\"') quotes = !quotes; else if (*s == '\\' && s + 1 != send) ++s; else if (*s == '(' && !quotes) ++parens; else if (*s == ')' && !quotes && parens) --parens; } String arg = str.substring(sarg, last_nonsp + 1); if (s != send) s = cp_skip_comment_space(s + 1, send); str = str.substring(s, send); return arg;}/***** * */inline bool comparison_char(char c){ return c == '=' || c == '!' || c == '>' || c == '<';}inline bool int_match_string(const char *begin, const char *end, int x, bool require_comparator = true){ int comparator = *begin++; if (begin < end && *begin == '=') { if (comparator == '>') comparator = 'G'; else if (comparator == '<') comparator = 'L'; ++begin; } else if (comparator == '!') return false; else if (!require_comparator && isdigit((unsigned char) comparator)) { comparator = '='; --begin; } int i; if (begin + 1 == end) i = *begin - '0'; else if (!cp_integer(begin, end, 10, &i)) return false; switch (comparator) { case '=': return x == i; case '!': return x != i; case '>': return x > i; case '<': return x < i; case 'G': return x >= i; case 'L': return x <= i; default: return false; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?