10 changed files with 579 additions and 562 deletions
@ -1,153 +0,0 @@ |
|||
|
|||
/*! |
|||
* Canvas - colors |
|||
* Copyright (c) 2010 LearnBoost <tj@learnboost.com> |
|||
* MIT Licensed |
|||
*/ |
|||
|
|||
module.exports = { |
|||
transparent: 'rgba(255,255,255,0)' |
|||
, aliceblue: '#f0f8ff' |
|||
, antiquewhite: '#faebd7' |
|||
, aqua: '#00ffff' |
|||
, aquamarine: '#7fffd4' |
|||
, azure: '#f0ffff' |
|||
, beige: '#f5f5dc' |
|||
, bisque: '#ffe4c4' |
|||
, black: '#000000' |
|||
, blanchedalmond: '#ffebcd' |
|||
, blue: '#0000ff' |
|||
, blueviolet: '#8a2be2' |
|||
, brown: '#a52a2a' |
|||
, burlywood: '#deb887' |
|||
, cadetblue: '#5f9ea0' |
|||
, chartreuse: '#7fff00' |
|||
, chocolate: '#d2691e' |
|||
, coral: '#ff7f50' |
|||
, cornflowerblue: '#6495ed' |
|||
, cornsilk: '#fff8dc' |
|||
, crimson: '#dc143c' |
|||
, cyan: '#00ffff' |
|||
, darkblue: '#00008b' |
|||
, darkcyan: '#008b8b' |
|||
, darkgoldenrod: '#b8860b' |
|||
, darkgray: '#a9a9a9' |
|||
, darkgreen: '#006400' |
|||
, darkkhaki: '#bdb76b' |
|||
, darkmagenta: '#8b008b' |
|||
, darkolivegreen: '#556b2f' |
|||
, darkorange: '#ff8c00' |
|||
, darkorchid: '#9932cc' |
|||
, darkred: '#8b0000' |
|||
, darksalmon: '#e9967a' |
|||
, darkseagreen: '#8fbc8f' |
|||
, darkslateblue: '#483d8b' |
|||
, darkslategray: '#2f4f4f' |
|||
, darkturquoise: '#00ced1' |
|||
, darkviolet: '#9400d3' |
|||
, deeppink: '#ff1493' |
|||
, deepskyblue: '#00bfff' |
|||
, dimgray: '#696969' |
|||
, dodgerblue: '#1e90ff' |
|||
, feldspar: '#d19275' |
|||
, firebrick: '#b22222' |
|||
, floralwhite: '#fffaf0' |
|||
, forestgreen: '#228b22' |
|||
, fuchsia: '#ff00ff' |
|||
, gainsboro: '#dcdcdc' |
|||
, ghostwhite: '#f8f8ff' |
|||
, gold: '#ffd700' |
|||
, goldenrod: '#daa520' |
|||
, gray: '#808080' |
|||
, green: '#008000' |
|||
, greenyellow: '#adff2f' |
|||
, honeydew: '#f0fff0' |
|||
, hotpink: '#ff69b4' |
|||
, indianred : '#cd5c5c' |
|||
, indigo : '#4b0082' |
|||
, ivory: '#fffff0' |
|||
, khaki: '#f0e68c' |
|||
, lavender: '#e6e6fa' |
|||
, lavenderblush: '#fff0f5' |
|||
, lawngreen: '#7cfc00' |
|||
, lemonchiffon: '#fffacd' |
|||
, lightblue: '#add8e6' |
|||
, lightcoral: '#f08080' |
|||
, lightcyan: '#e0ffff' |
|||
, lightgoldenrodyellow: '#fafad2' |
|||
, lightgrey: '#d3d3d3' |
|||
, lightgreen: '#90ee90' |
|||
, lightpink: '#ffb6c1' |
|||
, lightsalmon: '#ffa07a' |
|||
, lightseagreen: '#20b2aa' |
|||
, lightskyblue: '#87cefa' |
|||
, lightslateblue: '#8470ff' |
|||
, lightslategray: '#778899' |
|||
, lightsteelblue: '#b0c4de' |
|||
, lightyellow: '#ffffe0' |
|||
, lime: '#00ff00' |
|||
, limegreen: '#32cd32' |
|||
, linen: '#faf0e6' |
|||
, magenta: '#ff00ff' |
|||
, maroon: '#800000' |
|||
, mediumaquamarine: '#66cdaa' |
|||
, mediumblue: '#0000cd' |
|||
, mediumorchid: '#ba55d3' |
|||
, mediumpurple: '#9370d8' |
|||
, mediumseagreen: '#3cb371' |
|||
, mediumslateblue: '#7b68ee' |
|||
, mediumspringgreen: '#00fa9a' |
|||
, mediumturquoise: '#48d1cc' |
|||
, mediumvioletred: '#c71585' |
|||
, midnightblue: '#191970' |
|||
, mintcream: '#f5fffa' |
|||
, mistyrose: '#ffe4e1' |
|||
, moccasin: '#ffe4b5' |
|||
, navajowhite: '#ffdead' |
|||
, navy: '#000080' |
|||
, oldlace: '#fdf5e6' |
|||
, olive: '#808000' |
|||
, olivedrab: '#6b8e23' |
|||
, orange: '#ffa500' |
|||
, orangered: '#ff4500' |
|||
, orchid: '#da70d6' |
|||
, palegoldenrod: '#eee8aa' |
|||
, palegreen: '#98fb98' |
|||
, paleturquoise: '#afeeee' |
|||
, palevioletred: '#d87093' |
|||
, papayawhip: '#ffefd5' |
|||
, peachpuff: '#ffdab9' |
|||
, peru: '#cd853f' |
|||
, pink: '#ffc0cb' |
|||
, plum: '#dda0dd' |
|||
, powderblue: '#b0e0e6' |
|||
, purple: '#800080' |
|||
, red: '#ff0000' |
|||
, rosybrown: '#bc8f8f' |
|||
, royalblue: '#4169e1' |
|||
, saddlebrown: '#8b4513' |
|||
, salmon: '#fa8072' |
|||
, sandybrown: '#f4a460' |
|||
, seagreen: '#2e8b57' |
|||
, seashell: '#fff5ee' |
|||
, sienna: '#a0522d' |
|||
, silver: '#c0c0c0' |
|||
, skyblue: '#87ceeb' |
|||
, slateblue: '#6a5acd' |
|||
, slategray: '#708090' |
|||
, snow: '#fffafa' |
|||
, springgreen: '#00ff7f' |
|||
, steelblue: '#4682b4' |
|||
, tan: '#d2b48c' |
|||
, teal: '#008080' |
|||
, thistle: '#d8bfd8' |
|||
, tomato: '#ff6347' |
|||
, turquoise: '#40e0d0' |
|||
, violet: '#ee82ee' |
|||
, violetred: '#d02090' |
|||
, wheat: '#f5deb3' |
|||
, white: '#ffffff' |
|||
, whitesmoke: '#f5f5f5' |
|||
, yellow: '#ffff00' |
|||
, yellowgreen: '#9acd32' |
|||
}; |
@ -0,0 +1,423 @@ |
|||
|
|||
//
|
|||
// color.cc
|
|||
//
|
|||
// Copyright (c) 2010 LearnBoost <tj@learnboost.com>
|
|||
//
|
|||
|
|||
#include "color.h" |
|||
#include <stdlib.h> |
|||
|
|||
/*
|
|||
* Consume whitespace. |
|||
*/ |
|||
|
|||
#define WHITESPACE \ |
|||
while (' ' == *str) ++str; |
|||
|
|||
/*
|
|||
* Parse color channel value |
|||
*/ |
|||
|
|||
#define CHANNEL(NAME) \ |
|||
if (*str >= '0' && *str <= '9') { \ |
|||
do { \ |
|||
NAME *= 10; \ |
|||
NAME += *str++ - '0'; \ |
|||
} while (*str >= '0' && *str <= '9'); \ |
|||
} else { \ |
|||
return 0; \ |
|||
} \ |
|||
while (' ' == *str || ',' == *str) str++; |
|||
|
|||
/*
|
|||
* Named colors. |
|||
*/ |
|||
|
|||
static struct named_color { |
|||
const char *name; |
|||
uint32_t val; |
|||
} named_colors[] = { |
|||
{"transparent", 0xffffff00} |
|||
, {"aliceblue", 0xf0f8ffff} |
|||
, {"antiquewhite", 0xfaebd7ff} |
|||
, {"aqua", 0x00ffffff} |
|||
, {"aquamarine", 0x7fffd4ff} |
|||
, {"azure", 0xf0ffffff} |
|||
, {"beige", 0xf5f5dcff} |
|||
, {"bisque", 0xffe4c4ff} |
|||
, {"black", 0x000000ff} |
|||
, {"blanchedalmond", 0xffebcdff} |
|||
, {"blue", 0x0000ffff} |
|||
, {"blueviolet", 0x8a2be2ff} |
|||
, {"brown", 0xa52a2aff} |
|||
, {"burlywood", 0xdeb887ff} |
|||
, {"cadetblue", 0x5f9ea0ff} |
|||
, {"chartreuse", 0x7fff00ff} |
|||
, {"chocolate", 0xd2691eff} |
|||
, {"coral", 0xff7f50ff} |
|||
, {"cornflowerblue", 0x6495edff} |
|||
, {"cornsilk", 0xfff8dcff} |
|||
, {"crimson", 0xdc143cff} |
|||
, {"cyan", 0x00ffffff} |
|||
, {"darkblue", 0x00008bff} |
|||
, {"darkcyan", 0x008b8bff} |
|||
, {"darkgoldenrod", 0xb8860bff} |
|||
, {"darkgray", 0xa9a9a9ff} |
|||
, {"darkgreen", 0x006400ff} |
|||
, {"darkkhaki", 0xbdb76bff} |
|||
, {"darkmagenta", 0x8b008bff} |
|||
, {"darkolivegreen", 0x556b2fff} |
|||
, {"darkorange", 0xff8c00ff} |
|||
, {"darkorchid", 0x9932ccff} |
|||
, {"darkred", 0x8b0000ff} |
|||
, {"darksalmon", 0xe9967aff} |
|||
, {"darkseagreen", 0x8fbc8fff} |
|||
, {"darkslateblue", 0x483d8bff} |
|||
, {"darkslategray", 0x2f4f4fff} |
|||
, {"darkturquoise", 0x00ced1ff} |
|||
, {"darkviolet", 0x9400d3ff} |
|||
, {"deeppink", 0xff1493ff} |
|||
, {"deepskyblue", 0x00bfffff} |
|||
, {"dimgray", 0x696969ff} |
|||
, {"dodgerblue", 0x1e90ffff} |
|||
, {"feldspar", 0xd19275ff} |
|||
, {"firebrick", 0xb22222ff} |
|||
, {"floralwhite", 0xfffaf0ff} |
|||
, {"forestgreen", 0x228b22ff} |
|||
, {"fuchsia", 0xff00ffff} |
|||
, {"gainsboro", 0xdcdcdcff} |
|||
, {"ghostwhite", 0xf8f8ffff} |
|||
, {"gold", 0xffd700ff} |
|||
, {"goldenrod", 0xdaa520ff} |
|||
, {"gray", 0x808080ff} |
|||
, {"green", 0x008000ff} |
|||
, {"greenyellow", 0xadff2fff} |
|||
, {"honeydew", 0xf0fff0ff} |
|||
, {"hotpink", 0xff69b4ff} |
|||
, {"indianred ", 0xcd5c5cff} |
|||
, {"indigo ", 0x4b0082ff} |
|||
, {"ivory", 0xfffff0ff} |
|||
, {"khaki", 0xf0e68cff} |
|||
, {"lavender", 0xe6e6faff} |
|||
, {"lavenderblush", 0xfff0f5ff} |
|||
, {"lawngreen", 0x7cfc00ff} |
|||
, {"lemonchiffon", 0xfffacdff} |
|||
, {"lightblue", 0xadd8e6ff} |
|||
, {"lightcoral", 0xf08080ff} |
|||
, {"lightcyan", 0xe0ffffff} |
|||
, {"lightgoldenrodyellow", 0xfafa} |
|||
, {"lightgrey", 0xd3d3d3ff} |
|||
, {"lightgreen", 0x90ee90ff} |
|||
, {"lightpink", 0xffb6c1ff} |
|||
, {"lightsalmon", 0xffa07aff} |
|||
, {"lightseagreen", 0x20b2aaff} |
|||
, {"lightskyblue", 0x87cefaff} |
|||
, {"lightslateblue", 0x8470ffff} |
|||
, {"lightslategray", 0x778899ff} |
|||
, {"lightsteelblue", 0xb0c4deff} |
|||
, {"lightyellow", 0xffffe0ff} |
|||
, {"lime", 0x00ff00ff} |
|||
, {"limegreen", 0x32cd32ff} |
|||
, {"linen", 0xfaf0e6ff} |
|||
, {"magenta", 0xff00ffff} |
|||
, {"maroon", 0x800000ff} |
|||
, {"mediumaquamarine", 0x66cdaaff} |
|||
, {"mediumblue", 0x0000cdff} |
|||
, {"mediumorchid", 0xba55d3ff} |
|||
, {"mediumpurple", 0x9370d8ff} |
|||
, {"mediumseagreen", 0x3cb371ff} |
|||
, {"mediumslateblue", 0x7b68eeff} |
|||
, {"mediumspringgreen", 0x00fa9af} |
|||
, {"mediumturquoise", 0x48d1ccff} |
|||
, {"mediumvioletred", 0xc71585ff} |
|||
, {"midnightblue", 0x191970ff} |
|||
, {"mintcream", 0xf5fffaff} |
|||
, {"mistyrose", 0xffe4e1ff} |
|||
, {"moccasin", 0xffe4b5ff} |
|||
, {"navajowhite", 0xffdeadff} |
|||
, {"navy", 0x000080ff} |
|||
, {"oldlace", 0xfdf5e6ff} |
|||
, {"olive", 0x808000ff} |
|||
, {"olivedrab", 0x6b8e23ff} |
|||
, {"orange", 0xffa500ff} |
|||
, {"orangered", 0xff4500ff} |
|||
, {"orchid", 0xda70d6ff} |
|||
, {"palegoldenrod", 0xeee8aaff} |
|||
, {"palegreen", 0x98fb98ff} |
|||
, {"paleturquoise", 0xafeeeeff} |
|||
, {"palevioletred", 0xd87093ff} |
|||
, {"papayawhip", 0xffefd5ff} |
|||
, {"peachpuff", 0xffdab9ff} |
|||
, {"peru", 0xcd853fff} |
|||
, {"pink", 0xffc0cbff} |
|||
, {"plum", 0xdda0ddff} |
|||
, {"powderblue", 0xb0e0e6ff} |
|||
, {"purple", 0x800080ff} |
|||
, {"red", 0xff0000ff} |
|||
, {"rosybrown", 0xbc8f8fff} |
|||
, {"royalblue", 0x4169e1ff} |
|||
, {"saddlebrown", 0x8b4513ff} |
|||
, {"salmon", 0xfa8072ff} |
|||
, {"sandybrown", 0xf4a460ff} |
|||
, {"seagreen", 0x2e8b57ff} |
|||
, {"seashell", 0xfff5eeff} |
|||
, {"sienna", 0xa0522dff} |
|||
, {"silver", 0xc0c0c0ff} |
|||
, {"skyblue", 0x87ceebff} |
|||
, {"slateblue", 0x6a5acdff} |
|||
, {"slategray", 0x708090ff} |
|||
, {"snow", 0xfffafaff} |
|||
, {"springgreen", 0x00ff7fff} |
|||
, {"steelblue", 0x4682b4ff} |
|||
, {"tan", 0xd2b48cff} |
|||
, {"teal", 0x008080ff} |
|||
, {"thistle", 0xd8bfd8ff} |
|||
, {"tomato", 0xff6347ff} |
|||
, {"turquoise", 0x40e0d0ff} |
|||
, {"violet", 0xee82eeff} |
|||
, {"violetred", 0xd02090ff} |
|||
, {"wheat", 0xf5deb3ff} |
|||
, {"white", 0xffffffff} |
|||
, {"whitesmoke", 0xf5f5f5ff} |
|||
, {"yellow", 0xffff00ff} |
|||
, {"yellowgreen", 0x9acd32ff} |
|||
, {NULL, NULL} |
|||
}; |
|||
|
|||
/*
|
|||
* Hex digit int val. |
|||
*/ |
|||
|
|||
static int |
|||
h(char c) { |
|||
switch (c) { |
|||
case '0': |
|||
case '1': |
|||
case '2': |
|||
case '3': |
|||
case '4': |
|||
case '5': |
|||
case '6': |
|||
case '7': |
|||
case '8': |
|||
case '9': |
|||
return c - '0'; |
|||
case 'a': |
|||
case 'b': |
|||
case 'c': |
|||
case 'd': |
|||
case 'e': |
|||
case 'f': |
|||
return (c - 'a') + 10; |
|||
case 'A': |
|||
case 'B': |
|||
case 'C': |
|||
case 'D': |
|||
case 'E': |
|||
case 'F': |
|||
return (c - 'A') + 10; |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
/*
|
|||
* Return rgba_t from rgba. |
|||
*/ |
|||
|
|||
rgba_t |
|||
rgba_create(uint32_t rgba) { |
|||
rgba_t color; |
|||
color.r = (double) (rgba >> 24) / 255; |
|||
color.g = (double) ((rgba & 0x00ff0000) >> 16) / 255; |
|||
color.b = (double) ((rgba & 0x0000ff00) >> 8) / 255; |
|||
color.a = (double) (rgba & 0xff) / 255; |
|||
return color; |
|||
} |
|||
|
|||
/*
|
|||
* Return a string representation of the color. |
|||
*/ |
|||
|
|||
void |
|||
rgba_to_string(rgba_t rgba, char *buf) { |
|||
if (1 == rgba.a) { |
|||
sprintf(buf, "#%.2x%.2x%.2x" |
|||
, (int) (rgba.r * 255) |
|||
, (int) (rgba.g * 255) |
|||
, (int) (rgba.b * 255)); |
|||
} else { |
|||
sprintf(buf, "rgba(%d, %d, %d, %.2f)" |
|||
, (int) (rgba.r * 255) |
|||
, (int) (rgba.g * 255) |
|||
, (int) (rgba.b * 255) |
|||
, rgba.a); |
|||
} |
|||
} |
|||
|
|||
/*
|
|||
* Return rgba from (r,g,b,a). |
|||
*/ |
|||
|
|||
static inline int32_t |
|||
rgba_from_rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { |
|||
return |
|||
r << 24 |
|||
| g << 16 |
|||
| b << 8 |
|||
| a; |
|||
} |
|||
|
|||
/*
|
|||
* Return rgba from (r,g,b). |
|||
*/ |
|||
|
|||
static int32_t |
|||
rgba_from_rgb(uint8_t r, uint8_t g, uint8_t b) { |
|||
return rgba_from_rgba(r, g, b, 255); |
|||
} |
|||
|
|||
/*
|
|||
* Return rgb from "#RRGGBB". |
|||
*/ |
|||
|
|||
static int32_t |
|||
rgba_from_hex6_string(const char *str) { |
|||
return rgba_from_rgb( |
|||
(h(str[0]) << 4) + h(str[1]) |
|||
, (h(str[2]) << 4) + h(str[3]) |
|||
, (h(str[4]) << 4) + h(str[5]) |
|||
); |
|||
} |
|||
|
|||
/*
|
|||
* Return rgb from "#RGB" |
|||
*/ |
|||
|
|||
static int32_t |
|||
rgba_from_hex3_string(const char *str) { |
|||
return rgba_from_rgb( |
|||
(h(str[0]) << 4) + h(str[0]) |
|||
, (h(str[1]) << 4) + h(str[1]) |
|||
, (h(str[2]) << 4) + h(str[2]) |
|||
); |
|||
} |
|||
|
|||
/*
|
|||
* Return rgb from "rgb()" |
|||
*/ |
|||
|
|||
static int32_t |
|||
rgba_from_rgb_string(const char *str, short *ok) { |
|||
if (str == strnstr(str, "rgb(", 4)) { |
|||
str += 4; |
|||
WHITESPACE; |
|||
uint8_t r = 0, g = 0, b = 0; |
|||
CHANNEL(r); |
|||
CHANNEL(g); |
|||
CHANNEL(b); |
|||
return *ok = 1, rgba_from_rgb(r, g, b); |
|||
} |
|||
return *ok = 0; |
|||
} |
|||
|
|||
/*
|
|||
* Return rgb from "rgba()" |
|||
*/ |
|||
|
|||
static int32_t |
|||
rgba_from_rgba_string(const char *str, short *ok) { |
|||
if (str == strnstr(str, "rgba(", 5)) { |
|||
str += 5; |
|||
WHITESPACE; |
|||
uint8_t r = 0, g = 0, b = 0; |
|||
float a = 0; |
|||
CHANNEL(r); |
|||
CHANNEL(g); |
|||
CHANNEL(b); |
|||
// TODO: less strict
|
|||
if ('1' == *str) { |
|||
a = 1; |
|||
} else { |
|||
if ('0' == *str) a = 0, ++str; |
|||
if ('.' == *str) { |
|||
++str; |
|||
float n = .1; |
|||
while (*str >= '0' && *str <= '9') { |
|||
a += (*str++ - '0') * n; |
|||
n *= .1; |
|||
} |
|||
} |
|||
} |
|||
return *ok = 1, rgba_from_rgba(r, g, b, a * 255); |
|||
} |
|||
return *ok = 0; |
|||
} |
|||
|
|||
/*
|
|||
* Return rgb from: |
|||
* |
|||
* - "#RGB" |
|||
* - "#RRGGBB" |
|||
* |
|||
*/ |
|||
|
|||
static int32_t |
|||
rgba_from_hex_string(const char *str, short *ok) { |
|||
size_t len = strlen(str); |
|||
*ok = 1; |
|||
if (6 == len) return rgba_from_hex6_string(str); |
|||
if (3 == len) return rgba_from_hex3_string(str); |
|||
return *ok = 0; |
|||
} |
|||
|
|||
/*
|
|||
* Return named color value. |
|||
*/ |
|||
|
|||
static int32_t |
|||
rgba_from_name_string(const char *str, short *ok) { |
|||
int i = 0; |
|||
struct named_color color; |
|||
while ((color = named_colors[i++]).name) { |
|||
if (*str == *color.name && 0 == strcmp(str, color.name)) |
|||
return *ok = 1, color.val; |
|||
} |
|||
return *ok = 0; |
|||
} |
|||
|
|||
/*
|
|||
* Return rgb from: |
|||
* |
|||
* - #RGB |
|||
* - #RRGGBB |
|||
* - rgb(r,g,b) |
|||
* - rgba(r,g,b,a) |
|||
* - name |
|||
* |
|||
*/ |
|||
|
|||
int32_t |
|||
rgba_from_string(const char *str, short *ok) { |
|||
if ('#' == str[0]) |
|||
return rgba_from_hex_string(++str, ok); |
|||
if (str == strnstr(str, "rgba", 4)) |
|||
return rgba_from_rgba_string(str, ok); |
|||
if (str == strnstr(str, "rgb", 3)) |
|||
return rgba_from_rgb_string(str, ok); |
|||
return rgba_from_name_string(str, ok); |
|||
} |
|||
|
|||
/*
|
|||
* Inspect the given rgba color. |
|||
*/ |
|||
|
|||
void |
|||
rgba_inspect(int32_t rgba) { |
|||
printf("rgba(%d,%d,%d,%d)\n" |
|||
, rgba >> 24 & 0xFF |
|||
, rgba >> 16 & 0xFF |
|||
, rgba >> 8 & 0xFF |
|||
, rgba & 0xFF |
|||
); |
|||
} |
@ -0,0 +1,39 @@ |
|||
|
|||
//
|
|||
// color.h
|
|||
//
|
|||
// Copyright (c) 2010 LearnBoost <tj@learnboost.com>
|
|||
//
|
|||
|
|||
#ifndef __COLOR_PARSER_H__ |
|||
#define __COLOR_PARSER_H__ |
|||
|
|||
#include <stdio.h> |
|||
#include <stdint.h> |
|||
#include <string.h> |
|||
|
|||
/*
|
|||
* RGBA struct. |
|||
*/ |
|||
|
|||
typedef struct { |
|||
double r, g, b, a; |
|||
} rgba_t; |
|||
|
|||
/*
|
|||
* Prototypes. |
|||
*/ |
|||
|
|||
rgba_t |
|||
rgba_create(uint32_t rgba); |
|||
|
|||
int32_t |
|||
rgba_from_string(const char *str, short *ok); |
|||
|
|||
void |
|||
rgba_to_string(rgba_t rgba, char *buf); |
|||
|
|||
void |
|||
rgba_inspect(int32_t rgba); |
|||
|
|||
#endif /* __COLOR_PARSER_H__ */ |
Loading…
Reference in new issue