26 #define XFIG_DEFAULT_COLOR_COUNT 32 // colors "hardcoded" in fig format
27 #define XFIG_USER_COLOR_COUNT 512 // restriction defined by fig format
29 #define XFIG_USER_COLOR_FIRST XFIG_DEFAULT_COLOR_COUNT
30 #define XFIG_USER_COLOR_LAST (XFIG_USER_COLOR_FIRST+XFIG_USER_COLOR_COUNT-1)
38 virtual const char *text()
const = 0;
39 virtual const AW_rgb *rgb()
const = 0;
107 static const int NOT_ASSIGNED = -2;
132 return diff.
r()*diff.
r() + diff.
g()*diff.
g() + diff.
b()*diff.
b();
137 typedef map<AW_rgb,UsedColor> ColMap;
138 typedef map<AW_rgb,AW_rgb> Remap;
143 AW_rgb findCheapestReplaceableColor(
AW_rgb *replaceBy) {
147 for (ColMap::const_iterator i = color.begin(); i != color.end(); ++i) {
148 const AW_rgb& col1 = i->first;
149 if (i->second.isStdColor())
continue;
151 const int amount = i->second.getCount();
154 for (ColMap::const_iterator j = color.begin(); j != color.end(); ++j) {
155 const AW_rgb& col2 = j->first;
157 if (&col1 != &col2) {
159 #if defined(DEBUG) && 0
160 fprintf(stderr,
"replace %s ",
AW_rgb16(col1).ascii());
161 fprintf(stderr,
"by %s (amount=%i) -> penalty = %f\n",
AW_rgb16(col2).ascii(), amount, currPenalty);
164 if (currPenalty<penalty) {
165 penalty = currPenalty;
190 ColMap::const_iterator f1 = color.find(c1);
191 ColMap::const_iterator f2 = color.find(c2);
196 int cmp = f1->second.getCount() - f2->second.getCount();
197 if (!cmp) cmp = c1-c2;
202 size_t usedColors = color.size();
207 while (usedColors>allowed) {
209 AW_rgb cheapest = findCheapestReplaceableColor(&replaceBy);
211 aw_assert(!color[cheapest].isStdColor());
215 replaced[cheapest] = replaceBy;
216 color[replaceBy].addCount(color[cheapest].getCount());
226 vector<AW_rgb> sortedColors;
227 for (ColMap::iterator i = color.begin(); i != color.end(); ++i) {
228 sortedColors.push_back(i->first);
230 sort(sortedColors.begin(), sortedColors.end(), *
this);
234 for (ColMap::iterator i = color.begin(); i != color.end(); ++i) {
249 for (ColMap::const_iterator i = color.begin(); i != color.end(); ++i) {
250 #if defined(ASSERTION_USED)
251 const AW_rgb& rgb = i->first;
259 used[idx] = &(i->first);
265 fprintf(xout,
"0 %d #%06lx\n", i, *used[i]);
271 ColMap::const_iterator found = color.find(rgb);
272 while (found == color.end()) {
273 Remap::const_iterator remapped = replaced.find(rgb);
276 rgb = remapped->second;
277 found = color.find(rgb);
279 return found->second.getIndex();
292 typedef list<SpoolablePtr> Spoolables;
297 for (Spoolables::const_iterator i = objs.begin(); i != objs.end(); ++i) {
298 const AW_rgb *rgb = (*i)->rgb();
299 if (rgb) colmap.
add(*rgb);
317 while (!objs.empty()) {
321 const char *txt = next->text();
326 const AW_rgb *rgb = next->rgb();
330 fprintf(xout,
"%d ", idx);
348 #define spoolf(format) spooler->put(GBS_global_string format)
349 #define spools(str) spooler->put(str)
350 #define spoolColor(rgb) color_mode ? spooler->putColor(rgb) : spooler->putDefaultColor()
351 #define spoolDefaultColor() spooler->putDefaultColor()
354 bool drawflag =
false;
355 if (filteri & filter) {
358 drawflag = clip(transLine, clippedLine);
361 const AW_GC *gcm = get_common()->map_gc(gc);
365 double gap_ratio = 0.0;
368 case AW_DASHED: line_mode = 1; gap_ratio = 4.0;
break;
369 case AW_DOTTED: line_mode = 2; gap_ratio = 2.0;
break;
382 spoolf((
"0 0 0 0 %5.3f 0 1 0 0 0 2\n\t%d %d %d %d\n",
394 bool drawflag =
false;
395 if (filteri & filter) {
398 drawflag = !is_outside_clip(trans);
400 spoolf((
"2 1 0 1 7 7 50 -1 -1 0.000 0 0 -1 0 0 1\n\t%d %d\n",
408 void AW_device_print::draw_text(
int gc,
const char *textBuffer,
size_t textStart,
size_t textLen,
const AW::Position& pos) {
409 const AW_GC *gcm = get_common()->map_gc(gc);
413 char *pstr = strdup(textBuffer+textStart);
414 if (textLen < strlen(pstr)) pstr[textLen] = 0;
415 else textLen = strlen(pstr);
418 for (i=0; i<textLen; i++) {
419 if (pstr[i] <
' ') pstr[i] =
'?';
423 if (fontnr<0) fontnr = - fontnr;
433 spoolf((
"0 0 %d %d 0.000 4 %d %d %d %d ",
441 spoolf((
"%s\\001\n", pstr));
446 GB_ERROR AW_device_print::open(
const char *path) {
447 if (xfig)
return "You cannot reopen a device";
449 xfig = fopen(path,
"w");
470 for (
int i=0; i<data_colors_size; i++) {
471 if (color == data_colors[i]) {
478 int AW_device_print::find_color_idx(
AW_rgb color) {
481 idx = get_common()->find_data_color_idx(color);
487 void AW_device_print::close() {
491 spooler->spool(xfig);
502 DOWNCAST(AW_device_print*, device)->draw_text(gc, textBuffer, textStart, textLen, pos);
510 bool drawflag =
false;
511 if (filter & filteri) {
519 drawflag = polygon(gc, filled, 4, q, filteri);
522 drawflag = generic_box(gc, rect, filteri);
542 static const float PART = 1.0/22;
544 if (greylevel<PART)
return FS_EMPTY;
545 if (greylevel>(1.0-PART))
return FS_SOLID;
552 if (fillStyle == FS_SOLID) {
555 else if (fillStyle != FS_EMPTY) {
556 aw_assert(grey_level>=0.0 && grey_level<=1.0);
558 area_fill =
AW_INT(40-20*grey_level);
562 area_fill =
AW_INT(20*grey_level);
571 bool drawflag =
false;
572 if (filteri & filter) {
574 Rectangle Box(center-radius, center+radius);
577 drawflag = box_clip(screen_box, clipped_box);
578 bool half_visible = (clipped_box.
surface()*2) > screen_box.
surface();
580 drawflag = drawflag && half_visible;
584 const AW_GC *gcm = get_common()->map_gc(gc);
596 int subtype = (rx == ry) ? 3 : 1;
598 spoolf((
"1 %d ", subtype));
607 Fill_Style fillStyle = detectFillstyleForGreylevel(gc, filled);
611 if (area_fill == -1) {
617 spoolf((
"0 0 %d ", area_fill));
619 spoolf((
"0.000 1 0.0000 "));
622 spoolf((
"%d %d ", cx, cy));
623 spoolf((
"%d %d ", rx, ry));
624 spoolf((
"%d %d ", cx, cy));
632 bool drawflag =
false;
633 if (filteri && filter) {
635 Rectangle Box(center-radius, center+radius);
638 drawflag = box_clip(screen_box, clipped_box);
639 bool half_visible = (clipped_box.
surface()*2) > screen_box.
surface();
641 drawflag = drawflag && half_visible;
651 const AW_GC *gcm = get_common()->map_gc(gc);
662 bool use_spline = (rx != ry);
664 spools(use_spline ?
"3 4 " :
"5 1 ");
672 Fill_Style fillStyle = detectFillstyleForGreylevel(gc, filled);
676 if (area_fill == -1) {
682 spoolf((
"0 0 %d ", area_fill));
683 #if defined(UNIT_TESTS)
689 if (!use_spline)
spools(
"1 ");
697 const int MAX_ANGLE_STEP = 45;
699 int steps = (
abs(arc_degrees)-1)/MAX_ANGLE_STEP+1;
702 spoolf((
"%d\n\t", steps+1));
704 double rmax, x_factor, y_factor;
708 y_factor = double(ry)/rx;
712 x_factor = double(rx)/ry;
716 for (
int n = 0; n <= steps; ++n) {
717 Vector toCircle = a0.normal()*rmax;
718 Vector toEllipse(toCircle.
x()*x_factor, toCircle.
y()*y_factor);
719 Position onEllipse = Center+toEllipse;
727 if (n == steps-1) a0 = a1;
732 for (
int n = 0; n <= steps; ++n) {
734 spoolf((
" %d", (n == 0 || n == steps) ? 0 : -1));
739 spoolf((
"%d %d ", cx, cy));
743 double r = screen_radius.
x();
758 bool drawflag =
false;
759 if (filter & filteri) {
760 drawflag = generic_polygon(gc, npos, pos, filteri);
762 const AW_GC *gcm = get_common()->map_gc(gc);
771 Fill_Style fillStyle = detectFillstyleForGreylevel(gc, filled);
775 if (area_fill == -1) {
781 spoolf((
"0 0 %d ", area_fill));
784 spools(
"0.000 0 0 -1 0 0 ");
794 for (
int i=0; i <= npos; i++) {
795 int j = i == npos ? 0 : i;
797 Position transPos = transform(pos[j]);
799 ASSERT_RESULT(
bool,
true, force_into_clipbox(transPos, clippedPos));
AW_rgb get_last_fg_color() const
AW_linestyle get_line_style() const
int rgb2index(AW_rgb rgb) const
void putColor(AW_rgb rgb)
#define XFIG_DEFAULT_COLOR_COUNT
const AW_rgb * rgb() const OVERRIDE
int get_string_size(long textlen) const
Position centroid() const
short get_line_width() const
static bool AW_draw_string_on_printer(AW_device *device, int gc, const char *textBuffer, size_t textStart, size_t textLen, const AW::Position &pos, AW_CL)
const char * text() const OVERRIDE
int find_data_color_idx(AW_rgb color) const
#define ASSERT_RESULT(Type, Expected, Expr)
GB_ERROR GB_IO_error(const char *action, const char *filename)
SpoolableString(const char *txt)
int AW_font_2_xfig(AW_font font_nr)
double screen2printer(double val)
static AW_rgb figStdColors[32]
bool operator()(const AW_rgb &c1, const AW_rgb &c2) const
const char * text() const OVERRIDE
#define DOWNCAST(totype, expr)
SmartPtr< Spoolable > SpoolablePtr
#define XFIG_USER_COLOR_FIRST
static int diff(int v1, int v2, int v3, int v4, int st, int en)
static const double deg2rad
const double & ypos() const
const AW_rgb * rgb() const OVERRIDE
AW_font get_fontnr() const
Position lower_left_corner() const
const Position & upper_left_corner() const
AW_grey_level get_grey_level() const
short get_fontsize() const
void printUserColorDefinitions(FILE *xout)
const double & ypos() const
const Vector & diagonal() const
void mapColors(size_t allowed)
fputs(TRACE_PREFIX, stderr)
#define XFIG_USER_COLOR_COUNT
#define IF_ASSERTION_USED(x)
void put(const char *str)
#define XFIG_USER_COLOR_LAST
double colorDistSquare(const AW_rgb &col1, const AW_rgb &col2)
Position upper_right_corner() const
const double dpi_screen2printer
const double & xpos() const
int print_pos(AW_pos screen_pos)
Position lower_right_corner() const
const AW_font_limits & get_font_limits() const
SpoolableColor(const AW_rgb &color_)
#define spoolDefaultColor()
const double & xpos() const
GB_write_int const char s