⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 common.cc

📁 早期freebsd实现
💻 CC
📖 第 1 页 / 共 2 页
字号:
// -*- C++ -*-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.     Written by James Clark (jjc@jclark.com)This file is part of groff.groff is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the FreeSoftware Foundation; either version 2, or (at your option) any laterversion.groff is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY orFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public Licensefor more details.You should have received a copy of the GNU General Public License alongwith groff; see the file COPYING.  If not, write to the Free SoftwareFoundation, 675 Mass Ave, Cambridge, MA 02139, USA. */#include "pic.h"#include "common.h"// output a dashed circle as a series of arcsvoid common_output::dashed_circle(const position &cent, double rad,				  const line_type &lt){  assert(lt.type == line_type::dashed);  line_type slt = lt;  slt.type = line_type::solid;  double dash_angle = lt.dash_width/rad;  int ndashes;  double gap_angle;  if (dash_angle >= M_PI/4.0) {    if (dash_angle < M_PI/2.0) {      gap_angle = M_PI/2.0 - dash_angle;      ndashes = 4;    }    else if (dash_angle < M_PI) {      gap_angle = M_PI - dash_angle;      ndashes = 2;    }    else {      circle(cent, rad, slt, -1.0);      return;    }  }  else {    ndashes = 4*int(ceil(M_PI/(4.0*dash_angle)));    gap_angle = (M_PI*2.0)/ndashes - dash_angle;  }  for (int i = 0; i < ndashes; i++) {    double start_angle = i*(dash_angle+gap_angle) - dash_angle/2.0;    solid_arc(cent, rad, start_angle, start_angle + dash_angle, lt);  }}// output a dotted circle as a series of dotsvoid common_output::dotted_circle(const position &cent, double rad,				  const line_type &lt){  assert(lt.type == line_type::dotted);  double gap_angle = lt.dash_width/rad;  int ndots;  if (gap_angle >= M_PI/2.0) {    // always have at least 2 dots    gap_angle = M_PI;    ndots = 2;  }  else {    ndots = 4*int(M_PI/(2.0*gap_angle));    gap_angle = (M_PI*2.0)/ndots;  }  double ang = 0.0;  for (int i = 0; i < ndots; i++, ang += gap_angle)    dot(cent + position(cos(ang), sin(ang))*rad, lt);}// return non-zero iff we can compute a centerint compute_arc_center(const position &start, const position &cent,		       const position &end, position *result){  // This finds the point along the vector from start to cent that  // is equidistant between start and end.  distance c = cent - start;  distance e = end - start;  double n = c*e;  if (n == 0.0)    return 0;  *result = start + c*((e*e)/(2.0*n));  return 1;}// output a dashed arc as a series of arcsvoid common_output::dashed_arc(const position &start, const position &cent,			       const position &end, const line_type &lt){  assert(lt.type == line_type::dashed);  position c;  if (!compute_arc_center(start, cent, end, &c)) {    line(start, &end, 1, lt);    return;  }  distance start_offset = start - c;  distance end_offset = end - c;  double start_angle = atan2(start_offset.y, start_offset.x);  double end_angle = atan2(end_offset.y, end_offset.x);  double rad = hypot(c - start);  double dash_angle = lt.dash_width/rad;  double total_angle = end_angle - start_angle;  while (total_angle < 0)    total_angle += M_PI + M_PI;  if (total_angle <= dash_angle*2.0) {    solid_arc(cent, rad, start_angle, end_angle, lt);    return;  }  int ndashes = int((total_angle - dash_angle)/(dash_angle*2.0) + .5);  double dash_and_gap_angle = (total_angle - dash_angle)/ndashes;  for (int i = 0; i <= ndashes; i++)    solid_arc(cent, rad, start_angle + i*dash_and_gap_angle,	      start_angle + i*dash_and_gap_angle + dash_angle, lt);}// output a dotted arc as a series of dotsvoid common_output::dotted_arc(const position &start, const position &cent,			       const position &end, const line_type &lt){  assert(lt.type == line_type::dotted);  position c;  if (!compute_arc_center(start, cent, end, &c)) {    line(start, &end, 1, lt);    return;  }  distance start_offset = start - c;  distance end_offset = end - c;  double start_angle = atan2(start_offset.y, start_offset.x);  double total_angle = atan2(end_offset.y, end_offset.x) - start_angle;  while (total_angle < 0)    total_angle += M_PI + M_PI;  double rad = hypot(c - start);  int ndots = int(total_angle/(lt.dash_width/rad) + .5);  if (ndots == 0)    dot(start, lt);  else {    for (int i = 0; i <= ndots; i++) {      double a = start_angle + (total_angle*i)/ndots;      dot(cent + position(cos(a), sin(a))*rad, lt);    }  }}void common_output::solid_arc(const position &cent, double rad,			      double start_angle, double end_angle,			      const line_type &lt){  line_type slt = lt;  slt.type = line_type::solid;  arc(cent + position(cos(start_angle), sin(start_angle))*rad,      cent,      cent + position(cos(end_angle), sin(end_angle))*rad,      slt);}void common_output::rounded_box(const position &cent, const distance &dim,				double rad, const line_type &lt, double fill){  if (fill >= 0.0)    filled_rounded_box(cent, dim, rad, fill);  switch (lt.type) {  case line_type::invisible:    break;  case line_type::dashed:    dashed_rounded_box(cent, dim, rad, lt);    break;  case line_type::dotted:    dotted_rounded_box(cent, dim, rad, lt);    break;  case line_type::solid:    solid_rounded_box(cent, dim, rad, lt);    break;  default:    assert(0);  }}void common_output::dashed_rounded_box(const position &cent,				       const distance &dim, double rad,				       const line_type &lt){  line_type slt = lt;  slt.type = line_type::solid;  double hor_length = dim.x + (M_PI/2.0 - 2.0)*rad;  int n_hor_dashes = int(hor_length/(lt.dash_width*2.0) + .5);  double hor_gap_width = (n_hor_dashes != 0			  ? hor_length/n_hor_dashes - lt.dash_width			  : 0.0);  double vert_length = dim.y + (M_PI/2.0 - 2.0)*rad;  int n_vert_dashes = int(vert_length/(lt.dash_width*2.0) + .5);  double vert_gap_width = (n_vert_dashes != 0			   ? vert_length/n_vert_dashes - lt.dash_width			   : 0.0);  // Note that each corner arc has to be split into two for dashing,  // because one part is dashed using vert_gap_width, and the other  // using hor_gap_width.  double offset = lt.dash_width/2.0;  dash_arc(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad,	   -M_PI/4.0, 0, slt, lt.dash_width, vert_gap_width, &offset);  dash_line(cent + position(dim.x/2.0, -dim.y/2.0 + rad),	    cent + position(dim.x/2.0, dim.y/2.0 - rad),	    slt, lt.dash_width, vert_gap_width, &offset);  dash_arc(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad,	   0, M_PI/4.0, slt, lt.dash_width, vert_gap_width, &offset);  offset = lt.dash_width/2.0;  dash_arc(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad,	   M_PI/4.0, M_PI/2, slt, lt.dash_width, hor_gap_width, &offset);  dash_line(cent + position(dim.x/2.0 - rad, dim.y/2.0),	    cent + position(-dim.x/2.0 + rad, dim.y/2.0),	    slt, lt.dash_width, hor_gap_width, &offset);  dash_arc(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad,	   M_PI/2, 3*M_PI/4.0, slt, lt.dash_width, hor_gap_width, &offset);  offset = lt.dash_width/2.0;  dash_arc(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad,	   3.0*M_PI/4.0, M_PI, slt, lt.dash_width, vert_gap_width, &offset);  dash_line(cent + position(-dim.x/2.0, dim.y/2.0 - rad),	    cent + position(-dim.x/2.0, -dim.y/2.0 + rad),	    slt, lt.dash_width, vert_gap_width, &offset);  dash_arc(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad,	   M_PI, 5.0*M_PI/4.0, slt, lt.dash_width, vert_gap_width, &offset);  offset = lt.dash_width/2.0;  dash_arc(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad,	   5*M_PI/4.0, 3*M_PI/2.0, slt, lt.dash_width, hor_gap_width, &offset);  dash_line(cent + position(-dim.x/2.0 + rad, -dim.y/2.0),	    cent + position(dim.x/2.0 - rad, -dim.y/2.0),	    slt, lt.dash_width, hor_gap_width, &offset);  dash_arc(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad,	   3*M_PI/2, 7*M_PI/4, slt, lt.dash_width, hor_gap_width, &offset);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -