예제 #1
0
void wxSVGFileDCImpl::DoDrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord xc, wxCoord yc)
{
    /* Draws an arc of a circle, centred on (xc, yc), with starting point
    (x1, y1) and ending at (x2, y2). The current pen is used for the outline
    and the current brush for filling the shape.

    The arc is drawn in an anticlockwise direction from the start point to
    the end point.

    Might be better described as Pie drawing */

    NewGraphicsIfNeeded();
    wxString s;

    // we need the radius of the circle which has two estimates
    double r1 = sqrt ( double( (x1-xc)*(x1-xc) ) + double( (y1-yc)*(y1-yc) ) );
    double r2 = sqrt ( double( (x2-xc)*(x2-xc) ) + double( (y2-yc)*(y2-yc) ) );

    wxASSERT_MSG( (fabs ( r2-r1 ) <= 3), wxT("wxSVGFileDC::DoDrawArc Error in getting radii of circle"));
    if ( fabs ( r2-r1 ) > 3 )    //pixels
    {
        s = wxT("<!--- wxSVGFileDC::DoDrawArc Error in getting radii of circle --> \n");
        write(s);
    }

    double theta1 = atan2((double)(yc-y1),(double)(x1-xc));
    if ( theta1 < 0 ) theta1 = theta1 + M_PI * 2;
    double theta2 = atan2((double)(yc-y2), (double)(x2-xc));
    if ( theta2 < 0 ) theta2 = theta2 + M_PI * 2;
    if ( theta2 < theta1 ) theta2 = theta2 + M_PI *2;

    int fArc;                  // flag for large or small arc 0 means less than 180 degrees
    if ( fabs(theta2 - theta1) > M_PI ) fArc = 1;
    else fArc = 0;

    int fSweep = 0;             // flag for sweep always 0

    s.Printf ( wxT("<path d=\"M%d %d A%s %s 0.0 %d %d %d %d L%d %d z "),
               x1,y1, NumStr(r1), NumStr(r2), fArc, fSweep, x2, y2, xc, yc );

    // the z means close the path and fill
    s += wxT(" \" /> \n");


    if (m_OK)
    {
        write(s);
    }
}
예제 #2
0
static const char *
protoname(unsigned proto)
{
  static const char *cftypes[] = { "IFACEID", "COMPPROTO" };

  if (proto > 0 && proto <= sizeof cftypes / sizeof *cftypes)
    return cftypes[proto - 1];

  return NumStr(proto, NULL, 0);
}
예제 #3
0
void wxSVGFileDCImpl::DoStartNewGraphics()
{
    wxString s, sBrush, sPenCap, sPenJoin, sPenStyle, sLast;

    sBrush = wxS("<g style=\"") + wxBrushString(m_brush.GetColour(), m_brush.GetStyle())
            + wxPenString(m_pen.GetColour(), m_pen.GetStyle());

    switch ( m_pen.GetCap() )
    {
        case  wxCAP_PROJECTING :
            sPenCap = wxS("stroke-linecap:square; ");
            break;
        case  wxCAP_BUTT :
            sPenCap = wxS("stroke-linecap:butt; ");
            break;
        case    wxCAP_ROUND :
        default :
            sPenCap = wxS("stroke-linecap:round; ");
    }

    switch ( m_pen.GetJoin() )
    {
        case  wxJOIN_BEVEL :
            sPenJoin = wxS("stroke-linejoin:bevel; ");
            break;
        case  wxJOIN_MITER :
            sPenJoin = wxS("stroke-linejoin:miter; ");
            break;
        case    wxJOIN_ROUND :
        default :
            sPenJoin = wxS("stroke-linejoin:round; ");
    }

    sLast = wxString::Format(wxS("stroke-width:%d\" transform=\"translate(%s %s) scale(%s %s)\">"),
                 m_pen.GetWidth(),
                 NumStr((m_deviceOriginX - m_logicalOriginX)* m_signX),
                 NumStr((m_deviceOriginY - m_logicalOriginY)* m_signY),
                 NumStr(m_scaleX * m_signX),
                 NumStr(m_scaleY * m_signY));

    s = sBrush + sPenCap + sPenJoin + sPenStyle + sLast + wxS("\n");
    write(s);
}
예제 #4
0
파일: radius.c 프로젝트: coyizumi/cs111
static const char *
radius_policyname(int policy)
{
  switch(policy) {
  case MPPE_POLICY_ALLOWED:
    return "Allowed";
  case MPPE_POLICY_REQUIRED:
    return "Required";
  }
  return NumStr(policy, NULL, 0);
}
예제 #5
0
파일: radius.c 프로젝트: coyizumi/cs111
static const char *
radius_typesname(int types)
{
  switch(types) {
  case MPPE_TYPE_40BIT:
    return "40 bit";
  case MPPE_TYPE_128BIT:
    return "128 bit";
  case MPPE_TYPE_40BIT|MPPE_TYPE_128BIT:
    return "40 or 128 bit";
  }
  return NumStr(types, NULL, 0);
}
예제 #6
0
void wxSVGFileDCImpl::DoDrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius)
{
    NewGraphicsIfNeeded();
    wxString s;

    s = wxString::Format(wxS("  <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" rx=\"%s\"%s"),
                         x, y, width, height, NumStr(radius), wxGetBrushFill(m_brush));

    s += wxS("/>\n");
    write(s);

    CalcBoundingBox(x, y);
    CalcBoundingBox(x + width, y + height);
}
예제 #7
0
파일: route.c 프로젝트: Gwenio/DragonFlyBSD
const char *
Index2Nam(int idx)
{
  /*
   * XXX: Maybe we should select() on the routing socket so that we can
   *      notice interfaces that come & go (PCCARD support).
   *      Or we could even support a signal that resets these so that
   *      the PCCARD insert/remove events can signal ppp.
   */
  static char **ifs;		/* Figure these out once */
  static int debug_done;	/* Debug once */

  if (idx > route_nifs || (idx > 0 && ifs[idx-1] == NULL)) {
    int mib[6], have, had;
    size_t needed;
    char *buf, *ptr, *end;
    struct sockaddr_dl *dl;
    struct if_msghdr *ifm;

    if (ifs) {
      free(ifs);
      ifs = NULL;
      route_nifs = 0;
    }
    debug_done = 0;

    mib[0] = CTL_NET;
    mib[1] = PF_ROUTE;
    mib[2] = 0;
    mib[3] = 0;
    mib[4] = NET_RT_IFLIST;
    mib[5] = 0;

    if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {
      log_Printf(LogERROR, "Index2Nam: sysctl: estimate: %s\n",
                 strerror(errno));
      return NumStr(idx, NULL, 0);
    }
    if ((buf = malloc(needed)) == NULL)
      return NumStr(idx, NULL, 0);
    if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
      free(buf);
      return NumStr(idx, NULL, 0);
    }
    end = buf + needed;

    have = 0;
    for (ptr = buf; ptr < end; ptr += ifm->ifm_msglen) {
      ifm = (struct if_msghdr *)ptr;
      if (ifm->ifm_type != RTM_IFINFO)
        continue;
      dl = (struct sockaddr_dl *)(ifm + 1);
      if (ifm->ifm_index > 0) {
        if (ifm->ifm_index > have) {
          char **newifs;

          had = have;
          have = ifm->ifm_index + 5;
          if (had)
            newifs = (char **)realloc(ifs, sizeof(char *) * have);
          else
            newifs = (char **)malloc(sizeof(char *) * have);
          if (!newifs) {
            log_Printf(LogDEBUG, "Index2Nam: %s\n", strerror(errno));
            route_nifs = 0;
            if (ifs) {
              free(ifs);
              ifs = NULL;
            }
            free(buf);
            return NumStr(idx, NULL, 0);
          }
          ifs = newifs;
          memset(ifs + had, '\0', sizeof(char *) * (have - had));
        }
        if (ifs[ifm->ifm_index-1] == NULL) {
          ifs[ifm->ifm_index-1] = (char *)malloc(dl->sdl_nlen+1);
          memcpy(ifs[ifm->ifm_index-1], dl->sdl_data, dl->sdl_nlen);
          ifs[ifm->ifm_index-1][dl->sdl_nlen] = '\0';
          if (route_nifs < ifm->ifm_index)
            route_nifs = ifm->ifm_index;
        }
      } else if (log_IsKept(LogDEBUG))
        log_Printf(LogDEBUG, "Skipping out-of-range interface %d!\n",
                  ifm->ifm_index);
    }
    free(buf);
  }

  if (log_IsKept(LogDEBUG) && !debug_done) {
    int f;

    log_Printf(LogDEBUG, "Found the following interfaces:\n");
    for (f = 0; f < route_nifs; f++)
      if (ifs[f] != NULL)
        log_Printf(LogDEBUG, " Index %d, name \"%s\"\n", f+1, ifs[f]);
    debug_done = 1;
  }

  if (idx < 1 || idx > route_nifs || ifs[idx-1] == NULL)
    return NumStr(idx, NULL, 0);

  return ifs[idx-1];
}
예제 #8
0
/*******************************+++*******************************/
int CrossValidate(void)
/*****************************************************************/
/*   Purpose:  Compute cross validations and put them in the CV  */
/*             matrix.                                           */
/*                                                               */
/*   1996.04.12: Completed removed.                              */
/*   1996.04.04: X and y include NA's.                           */
/*   1996.04.14: KrigModAlloc/KrigModData; DbIndexXY.            */
/*   2009.05.07: Multiple correlation families                   */
/*****************************************************************/
{
    int            ErrNum, ErrReturn;
    KrigingModel   KrigMod;
    real           *CVMaxErr, *CVRootMSE, *ErrVar, *PredCol;
    real           *SE, *SECol, *SPVar, *YHatCV;
    size_t         IndexMaxErr, j;
    string         ColName;
    string         *CaseMaxErr;

    if (MatNumCols(&T) > 0)
    {
        Error("Transformations not allowed.\n");
        return INPUT_ERR;
    }

    ErrVar = MatColFind(&YDescrip, ERR_VAR, NO);
    SPVar  = MatColFind(&YDescrip, SP_VAR, YES);

    /* Add columns to the YDescrip matrix. */
    CVRootMSE  = MatColAdd(CV_ROOT_MSE,        &YDescrip);
    CVMaxErr   = MatColAdd(CV_MAX_ERR,         &YDescrip);
    CaseMaxErr = MatStrColAdd(CASE_CV_MAX_ERR, &YDescrip);

    /* Compute cross-validation predictions for each response. */
    ErrReturn = OK;
    ErrorSave = YES;
    for (j = 0; j < MatNumRows(&YDescrip); j++)
    {
        if (DbIndexXY(j) == 0)
            continue;

        ErrorVar = yName;

        /* Allocations. */
        YHatCV = AllocReal(nCasesXY, NULL);
        SE     = AllocReal(nCasesXY, NULL);

        /* Set up kriging model. */
        KrigModAlloc(nCasesXY, MatNumCols(&X), yName, &T, &RegMod,
                     &SPMod, CorFamNum, RanErr, &KrigMod);
        KrigModData(nCasesXY, IndexXY, &X, y, &KrigMod);

        /* SPModMat contains the correlation parameters. */
        ErrNum = KrigModSetUp(&SPModMat, yName, SPVar[j],
                              (ErrVar != NULL) ? ErrVar[j] : 0.0, &KrigMod);

        if (ErrNum == OK)
            ErrNum = CalcCV(&KrigMod, YHatCV, SE);

        if (ErrNum == OK)
        {
            /* Put cross validations and standard errors */
            /* in CV.                                    */

            ColName = StrPaste(3, PRED, ".", yName);
            PredCol = MatColAdd(ColName, &CV);
            AllocFree(ColName);
            VecCopyIndex(nCasesXY, NULL, YHatCV, IndexXY,
                         PredCol);

            ColName = StrPaste(3, STD_ERR, ".", yName);
            SECol = MatColAdd(ColName, &CV);
            AllocFree(ColName);
            VecCopyIndex(nCasesXY, NULL, SE, IndexXY, SECol);

            /* Compute summary statistics. */
            CVRootMSE[j] = RootMSE(MatNumRows(&CV), PredCol, y,
                                   &CVMaxErr[j], &IndexMaxErr);
            if (IndexMaxErr != INDEX_ERR)
                CaseMaxErr[j] = StrReplace(
                                    MatRowName(&X, IndexMaxErr),
                                    CaseMaxErr[j]);

        }

        KrigModFree(&KrigMod);

        if (ErrNum != OK)
            ErrReturn = ErrNum;

        AllocFree(YHatCV);
        AllocFree(SE);
    }

    OutputSummary(&YDescrip, NumStr(SummaryStats), SummaryStats);

    return ErrReturn;
}
예제 #9
0
void wxSVGFileDCImpl::DoDrawRotatedText(const wxString& sText, wxCoord x, wxCoord y, double angle)
{
    //known bug; if the font is drawn in a scaled DC, it will not behave exactly as wxMSW
    NewGraphicsIfNeeded();
    wxString s, sTmp;

    // calculate bounding box
    wxCoord w, h, desc;
    DoGetTextExtent(sText, &w, &h, &desc);

    double rad = wxDegToRad(angle);

    // wxT("upper left") and wxT("upper right")
    CalcBoundingBox(x, y);
    CalcBoundingBox((wxCoord)(x + w*cos(rad)), (wxCoord)(y - h*sin(rad)));

    // wxT("bottom left") and wxT("bottom right")
    CalcBoundingBox((wxCoord)(x + h*sin(rad)), (wxCoord)(y + h*cos(rad)));
    CalcBoundingBox((wxCoord)(x + h*sin(rad) + w*cos(rad)), (wxCoord)(y + h*cos(rad) - w*sin(rad)));

    if (m_backgroundMode == wxBRUSHSTYLE_SOLID)
    {
        // draw background first
        // just like DoDrawRectangle except we pass the text color to it and set the border to a 1 pixel wide text background

        sTmp.Printf ( wxT(" <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" "), x, y, w, h );
        s = sTmp + wxT("style=\"") + wxBrushString(m_textBackgroundColour);
        s += wxT("stroke-width:1; ") + wxPenString(m_textBackgroundColour);
        sTmp.Printf ( wxT("\" transform=\"rotate( %s %d %d )  \" />"), NumStr(-angle), x,y );
        s += sTmp + wxT("\n");
        write(s);
    }

    // convert x,y to SVG text x,y (the coordinates of the text baseline)
    x = (wxCoord)(x + (h-desc)*sin(rad));
    y = (wxCoord)(y + (h-desc)*cos(rad));

    //now do the text itself
    s.Printf (wxT(" <text x=\"%d\" y=\"%d\" "),x,y );

    sTmp = m_font.GetFaceName();
    if (sTmp.Len() > 0)  s += wxT("style=\"font-family:") + sTmp + wxT("; ");
    else s += wxT("style=\" ");

    wxString fontweights [3] = { wxT("normal"), wxT("lighter"), wxT("bold") };
    s += wxT("font-weight:") + fontweights[m_font.GetWeight() - wxNORMAL] + wxT("; ");

    wxString fontstyles [5] = { wxT("normal"), wxT("style error"), wxT("style error"), wxT("italic"), wxT("oblique") };
    s += wxT("font-style:") + fontstyles[m_font.GetStyle() - wxNORMAL] + wxT("; ");

    sTmp.Printf (wxT("font-size:%dpt; "), m_font.GetPointSize() );
    s += sTmp;
    //text will be solid, unless alpha value isn't opaque in the foreground colour
    s += wxBrushString(m_textForegroundColour) + wxPenString(m_textForegroundColour);
    sTmp.Printf ( wxT("stroke-width:0;\"  transform=\"rotate( %s %d %d )  \" >"),  NumStr(-angle), x,y );
    s += sTmp + wxMarkupParser::Quote(sText) + wxT("</text> ") + wxT("\n");
    if (m_OK)
    {
        write(s);
    }
}
예제 #10
0
void wxSVGFileDCImpl::Init (const wxString &filename, int Width, int Height, double dpi)
{
    m_width = Width;
    m_height = Height;

    m_dpi = dpi;

    m_OK = true;

    m_clipUniqueId = 0;
    m_clipNestingLevel = 0;

    m_mm_to_pix_x = dpi/25.4;
    m_mm_to_pix_y = dpi/25.4;

    m_backgroundBrush = *wxTRANSPARENT_BRUSH;
    m_textForegroundColour = *wxBLACK;
    m_textBackgroundColour = *wxWHITE;
    m_colour = wxColourDisplay();

    m_pen   = *wxBLACK_PEN;
    m_font  = *wxNORMAL_FONT;
    m_brush = *wxWHITE_BRUSH;

    m_graphics_changed = true;

    ////////////////////code here

    m_bmp_handler = NULL;
    m_outfile = new wxFileOutputStream(filename);
    m_OK = m_outfile->IsOk();
    if (m_OK)
    {
        m_filename = filename;
        m_sub_images = 0;
        wxString s;
        s = wxT("<?xml version=\"1.0\" standalone=\"no\"?>\n");
        write(s);
        s = wxT("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\"\n");
        write(s);
        s = wxT("\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n");
        write(s);
        s = wxT("<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n");
        write(s);
        s.Printf( wxT("    width=\"%scm\" height=\"%scm\" viewBox=\"0 0 %d %d \">\n"), NumStr(float(Width)/dpi*2.54), NumStr(float(Height)/dpi*2.54), Width, Height );
        write(s);
        s = wxT("<title>SVG Picture created as ") + wxFileName(filename).GetFullName() + wxT(" </title>\n");
        write(s);
        s = wxString (wxT("<desc>Picture generated by wxSVG ")) + wxSVGVersion + wxT(" </desc>\n");
        write(s);
        s =  wxT("<g style=\"fill:black; stroke:black; stroke-width:1\">\n");
        write(s);
    }
}
예제 #11
0
static string SuppName[]      = SUPPORT_NAMES;
static string TransName[]     = TRANSFORM_NAMES;

/* Table for string-column templates. */
static struct StrColStruct
{
     string    Name;
     size_t    nLegalStrs;
     string    *LegalStr;
}
StrCol[] =
{
     {ANALYZE,           2,                   NoYes           },
     {CASE_MAX_ERR,      0,                   NULL            },
     {CASE_CV_MAX_ERR,   0,                   NULL            },
     {DISTRIBUTION,      NumStr(DistribName), DistribName     },
     {INCLUSIVE,         2,                   NoYes           },
     {SUPPORT,           NumStr(SuppName),    SuppName        },
     {TERM,              0,                   NULL            },
     {TRANSFORMATION,    NumStr(TransName),   TransName       },
     {UNITS,             0,                   NULL            },
     {VARIABLE,          0,                   NULL            }
};

#define NUM_STR_COLS  (sizeof(StrCol) / sizeof(struct StrColStruct))

/*******************************+++*******************************/
void DbColTemplInit(void)
/*****************************************************************/
/*   Purpose:  Initialize column templates.                      */
/*                                                               */
예제 #12
0
파일: db.c 프로젝트: Dustin21/GaSP-Ensemble
/******************************+++********************************/
int DbCheck(const string Name)
/*****************************************************************/
/*   Purpose:  Return status of database object and add a row to */
/*             DbStatus.                                         */
/*                                                               */
/*   Returns:  INPUT_ERR, INCOMPAT_ERR, or OK.                   */
/*                                                               */
/*   Version:  1996.02.11                                        */
/*****************************************************************/
{
     DbMatrix  *D;
     int       ErrNum;
     size_t    j, Row, Index;

     if (stricmp(Name, EXP_REG) == 0)
     {
          if ( (ErrNum = RegExtract(&XDescrip, X_DESCRIP, "." FIT,
                    &ExpReg)) == OK)
               ErrNum = RegCandCompat(&Cand, &ExpReg);

     }

     else if (stricmp(Name, PRED_REG) == 0)
     {
          if ( (ErrNum = RegExtract(&XDescrip, X_DESCRIP, "." PRED,
                    &PredReg)) == OK)
               ErrNum = RegCandCompat(&Cand, &PredReg);
     }

     if (stricmp(Name, EXP_REG) == 0 ||
               stricmp(Name, PRED_REG) == 0)
     {
          if (ErrNum != OK)
          {
               Row = StrIndex(X_DESCRIP,
                         MatStrCol(&DbStatus, DB_STATUS_OBJ_COL),
                         MatNumRows(&DbStatus));
               MatPutStrElem(&DbStatus, Row, DB_STATUS_OK_COL, NO_STR);
          }
          return ErrNum;
     }

     if (MatNumRows(&DbStatus) == 0)
     {
          MatAllocate(1, NumStr(DbStatusColName), RECT, MIXED,
                    DbStatusColType, YES, &DbStatus);
          for (j = 0; j < MatNumCols(&DbStatus); j++)
               MatPutColName(&DbStatus, j, DbStatusColName[j]);
          MatPutText(&DbStatus, "Database status:\n");
     }
     else
          /* Add a new row to DbStatus. */
          MatReAlloc(MatNumRows(&DbStatus) + 1,
                    MatNumCols(&DbStatus), &DbStatus);

     /* Status information goes in this row. */
     Row = MatNumRows(&DbStatus) - 1;

     MatPutStrElem(&DbStatus, Row, DB_STATUS_OBJ_COL, Name);

     if ( (Index = DbScalIndex(Name, NO)) != INDEX_ERR)
     {
          MatPutStrElem(&DbStatus, Row, DB_STATUS_CLASS_COL,
                    "Scalar");
          ErrNum = DbScalCheck(Index);
          MatPutStrElem(&DbStatus, Row, DB_STATUS_VAL_COL,
                    DbScalValue(Index));
          MatPutSize_tElem(&DbStatus, Row, DB_STATUS_ROWS_COL,
                    NA_SIZE_T);
          MatPutSize_tElem(&DbStatus, Row, DB_STATUS_COLS_COL,
                    NA_SIZE_T);

          if (ErrNum == OK && stricmp(Name, DESIGN_CRIT) == 0)
               /* Errors in subsequent input ignored. */
               CritInput(CritNum);
     }
     else
     {
          MatPutStrElem(&DbStatus, Row, DB_STATUS_CLASS_COL,
                    "Matrix");
          D = DbMatFind(Name, YES);

          ErrNum = DbMatCheck(D,
                    &MatStrElem(&DbStatus, Row, DB_STATUS_VAL_COL));
          MatPutSize_tElem(&DbStatus, Row, DB_STATUS_ROWS_COL,
                    D->M->NumRows);
          MatPutSize_tElem(&DbStatus, Row, DB_STATUS_COLS_COL,
                    D->M->NumCols);

          if (D->IsOutput == YES ||
                    ((stricmp(Name, REG_MOD) == 0 ||
                    stricmp(Name, SP_MOD) == 0) &&
                    stricmp(FuncName, "Fit") == 0))
               /* Store the matrix title as the row name:  */
               /* Will be used later in DbOutputMatStatus. */
               MatPutRowName(&DbStatus, Row, D->Title);
     }

     MatPutStrElem(&DbStatus, Row, DB_STATUS_OK_COL, (ErrNum == OK) ?
               YES_STR : NO_STR);

     /* Always override defaults. */
     if (stricmp(Name, RAN_NUM_SEED) == 0)
          RandInit(Seed, Seed, Seed);

     return ErrNum;
}
예제 #13
0
void wxSVGFileDCImpl::DoDrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h, double sa, double ea)
{
    /*
    Draws an arc of an ellipse. The current pen is used for drawing the arc
    and the current brush is used for drawing the pie.

    x and y specify the x and y coordinates of the upper-left corner of the
    rectangle that contains the ellipse.

    width and height specify the width and height of the rectangle that
    contains the ellipse.

    start and end specify the start and end of the arc relative to the
    three-o'clock position from the center of the rectangle. Angles are
    specified in degrees (360 is a complete circle). Positive values mean
    counter-clockwise motion. If start is equal to end, a complete ellipse
    will be drawn. */

    //radius
    double rx = w / 2.0;
    double ry = h / 2.0;
    // center
    double xc = x + rx;
    double yc = y + ry;

    // start and end coords
    double xs, ys, xe, ye;
    xs = xc + rx * cos (wxDegToRad(sa));
    xe = xc + rx * cos (wxDegToRad(ea));
    ys = yc - ry * sin (wxDegToRad(sa));
    ye = yc - ry * sin (wxDegToRad(ea));

    // svg arcs have 0 degrees at 12-o'clock instead of 3-o'clock
    double start = (sa - 90);
    if (start < 0)
        start += 360;
    while (abs(start) > 360)
        start -= (start / abs(start)) * 360;

    double end = (ea - 90);
    if (end < 0)
        end += 360;
    while (abs(end) > 360)
        end -= (end / abs(end)) * 360;

    // svg arcs are in clockwise direction, reverse angle
    double angle = end - start;
    if (angle <= 0)
        angle += 360;

    int fArc = angle > 180 ? 1 : 0; // flag for large or small arc
    int fSweep = 0;                 // flag for sweep always 0

    wxString arcPath;
    if (angle == 360)
    {
        // Drawing full circle fails with default arc. Draw two half arcs instead.
        fArc = 1;
        arcPath = wxString::Format(wxS("  <path d=\"M%s %s a%s %s 0 %d %d %s %s a%s %s 0 %d %d %s %s"),
            NumStr(x), NumStr(y + ry),
            NumStr(rx), NumStr(ry), fArc, fSweep, NumStr( rx * 2), NumStr(0),
            NumStr(rx), NumStr(ry), fArc, fSweep, NumStr(-rx * 2), NumStr(0));
    }
    else
    {
        arcPath = wxString::Format(wxS("  <path d=\"M%s %s A%s %s 0 %d %d %s %s"),
            NumStr(xs), NumStr(ys),
            NumStr(rx), NumStr(ry), fArc, fSweep, NumStr(xe), NumStr(ye));
    }

    // Workaround so SVG does not draw an extra line from the centre of the drawn arc
    // to the start point of the arc.
    // First draw the arc with the current brush, without a border,
    // then draw the border without filling the arc.
    if (GetBrush().GetStyle() != wxBRUSHSTYLE_TRANSPARENT)
    {
        wxDCPenChanger setTransp(*GetOwner(), *wxTRANSPARENT_PEN);
        NewGraphicsIfNeeded();

        wxString arcFill = arcPath;
        arcFill += wxString::Format(wxS(" L%s %s z"), NumStr(xc), NumStr(yc));
        arcFill += wxS("\"/>\n");
        write(arcFill);
    }

    wxDCBrushChanger setTransp(*GetOwner(), *wxTRANSPARENT_BRUSH);
    NewGraphicsIfNeeded();

    wxString arcLine = arcPath + wxS("\"/>\n");
    write(arcLine);
}
예제 #14
0
void wxSVGFileDCImpl::DoDrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord xc, wxCoord yc)
{
    /* Draws an arc of a circle, centred on (xc, yc), with starting point
    (x1, y1) and ending at (x2, y2). The current pen is used for the outline
    and the current brush for filling the shape.

    The arc is drawn in an anticlockwise direction from the start point to
    the end point.

    Might be better described as Pie drawing */

    NewGraphicsIfNeeded();
    wxString s;

    // we need the radius of the circle which has two estimates
    double r1 = sqrt ( double( (x1-xc)*(x1-xc) ) + double( (y1-yc)*(y1-yc) ) );
    double r2 = sqrt ( double( (x2-xc)*(x2-xc) ) + double( (y2-yc)*(y2-yc) ) );

    wxASSERT_MSG( (fabs ( r2-r1 ) <= 3), wxS("wxSVGFileDC::DoDrawArc Error in getting radii of circle"));
    if ( fabs ( r2-r1 ) > 3 )    //pixels
    {
        s = wxS("<!--- wxSVGFileDC::DoDrawArc Error in getting radii of circle -->\n");
        write(s);
    }

    double theta1 = atan2((double)(yc - y1), (double)(x1 - xc));
    if (theta1 < 0)
        theta1 = theta1 + M_PI * 2;

    double theta2 = atan2((double)(yc - y2), (double)(x2 - xc));
    if (theta2 < 0)
        theta2 = theta2 + M_PI * 2;
    if (theta2 < theta1) theta2 = theta2 + M_PI * 2;

    int fArc;                  // flag for large or small arc 0 means less than 180 degrees
    if (fabs(theta2 - theta1) > M_PI)
        fArc = 1; else fArc = 0;

    int fSweep = 0;             // flag for sweep always 0

    if (x1 == x2 && y1 == y2)
    {
        // drawing full circle fails with default arc. Draw two half arcs instead.
        s = wxString::Format(wxS("  <path d=\"M%d %d a%s %s 0 %d %d %s %s a%s %s 0 %d %d %s %s"),
            x1, y1,
            NumStr(r1), NumStr(r2), fArc, fSweep, NumStr( r1 * 2), NumStr(0),
            NumStr(r1), NumStr(r2), fArc, fSweep, NumStr(-r1 * 2), NumStr(0));
    }
    else
    {
        // comply to wxDC specs by drawing closing line if brush is not transparent
        wxString line;
        if (GetBrush().GetStyle() != wxBRUSHSTYLE_TRANSPARENT)
            line = wxString::Format(wxS("L%d %d z"), xc, yc);

        s = wxString::Format(wxS("  <path d=\"M%d %d A%s %s 0 %d %d %d %d %s"),
            x1, y1, NumStr(r1), NumStr(r2), fArc, fSweep, x2, y2, line);
    }

    s += wxS("\"/>\n");

    write(s);
}
예제 #15
0
void wxSVGFileDCImpl::DoDrawRotatedText(const wxString& sText, wxCoord x, wxCoord y, double angle)
{
    //known bug; if the font is drawn in a scaled DC, it will not behave exactly as wxMSW
    NewGraphicsIfNeeded();
    wxString s;

    // Get extent of whole text.
    wxCoord w, h, heightLine;
    GetOwner()->GetMultiLineTextExtent(sText, &w, &h, &heightLine);

    // Compute the shift for the origin of the next line.
    const double rad = wxDegToRad(angle);
    const double dx = heightLine * sin(rad);
    const double dy = heightLine * cos(rad);

    // wxS("upper left") and wxS("upper right")
    CalcBoundingBox(x, y);
    CalcBoundingBox((wxCoord)(x + w*cos(rad)), (wxCoord)(y - h*sin(rad)));

    // wxS("bottom left") and wxS("bottom right")
    CalcBoundingBox((wxCoord)(x + h*sin(rad)), (wxCoord)(y + h*cos(rad)));
    CalcBoundingBox((wxCoord)(x + h*sin(rad) + w*cos(rad)), (wxCoord)(y + h*cos(rad) - w*sin(rad)));

    if (m_backgroundMode == wxBRUSHSTYLE_SOLID)
    {
        // draw background first
        // just like DoDrawRectangle except we pass the text color to it and set the border to a 1 pixel wide text background
        s += wxString::Format(wxS("  <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" "), x, y, w, h);
        s += wxS("style=\"") + wxBrushString(m_textBackgroundColour);
        s += wxS("stroke-width:1; ") + wxPenString(m_textBackgroundColour);
        s += wxString::Format(wxS("\" transform=\"rotate(%s %d %d)\"/>"), NumStr(-angle), x, y);
        s += wxS("\n");
        write(s);
    }

    // Draw all text line by line
    const wxArrayString lines = wxSplit(sText, '\n', '\0');
    for (size_t lineNum = 0; lineNum < lines.size(); lineNum++)
    {
        // convert x,y to SVG text x,y (the coordinates of the text baseline)
        wxCoord ww, hh, desc;
        DoGetTextExtent(lines[lineNum], &ww, &hh, &desc);
        int xx = x + wxRound(lineNum * dx) + (hh - desc) * sin(rad);
        int yy = y + wxRound(lineNum * dy) + (hh - desc) * cos(rad);

        //now do the text itself
        s += wxString::Format(wxS("  <text x=\"%d\" y=\"%d\" textLength=\"%d\" "), xx, yy, ww);

        wxString fontName(m_font.GetFaceName());
        if (fontName.Len() > 0)
            s += wxS("style=\"font-family:") + fontName + wxS("; ");
        else
            s += wxS("style=\" ");

        wxString fontweight;
        switch (m_font.GetWeight())
        {
            case wxFONTWEIGHT_MAX:
                wxFAIL_MSG(wxS("invalid font weight value"));
                wxFALLTHROUGH;

            case wxFONTWEIGHT_NORMAL:
                fontweight = wxS("normal");
                break;

            case wxFONTWEIGHT_LIGHT:
                fontweight = wxS("lighter");
                break;

            case wxFONTWEIGHT_BOLD:
                fontweight = wxS("bold");
                break;
        }

        wxASSERT_MSG(!fontweight.empty(), wxS("unknown font weight value"));

        s += wxS("font-weight:") + fontweight + wxS("; ");

        wxString fontstyle;
        switch (m_font.GetStyle())
        {
            case wxFONTSTYLE_MAX:
                wxFAIL_MSG(wxS("invalid font style value"));
                wxFALLTHROUGH;

            case wxFONTSTYLE_NORMAL:
                fontstyle = wxS("normal");
                break;

            case wxFONTSTYLE_ITALIC:
                fontstyle = wxS("italic");
                break;

            case wxFONTSTYLE_SLANT:
                fontstyle = wxS("oblique");
                break;
        }

        wxASSERT_MSG(!fontstyle.empty(), wxS("unknown font style value"));

        s += wxS("font-style:") + fontstyle + wxS("; ");

        wxString textDecoration;
        if (m_font.GetUnderlined())
            textDecoration += wxS(" underline");
        if (m_font.GetStrikethrough())
            textDecoration += wxS(" line-through");
        if (textDecoration.IsEmpty())
            textDecoration = wxS(" none");

        s += wxS("text-decoration:") + textDecoration + wxS("; ");

        s += wxString::Format(wxS("font-size:%dpt; "), m_font.GetPointSize());
        //text will be solid, unless alpha value isn't opaque in the foreground colour
        s += wxBrushString(m_textForegroundColour) + wxPenString(m_textForegroundColour);
        s += wxString::Format(wxS("stroke-width:0;\" transform=\"rotate(%s %d %d)\""), NumStr(-angle), xx, yy);
        s += wxS(" xml:space=\"preserve\">");
        s += wxMarkupParser::Quote(lines[lineNum]) + wxS("</text>\n");

        write(s);
    }
}