char32 *str_replace_literal (const char32 *string, const char32 *search, const char32 *replace, long maximumNumberOfReplaces, long *nmatches) { if (string == 0 || search == 0 || replace == 0) { return NULL; } int len_string = str32len (string); if (len_string == 0) { maximumNumberOfReplaces = 1; } int len_search = str32len (search); if (len_search == 0) { maximumNumberOfReplaces = 1; } /* To allocate memory for 'result' only once, we have to know how many matches will occur. */ const char32 *pos = string; //current position / start of current match *nmatches = 0; if (maximumNumberOfReplaces <= 0) { maximumNumberOfReplaces = LONG_MAX; } if (len_search == 0) { /* Search is empty string... */ if (len_string == 0) { *nmatches = 1; /* ...only matches empty string */ } } else { if (len_string != 0) { /* Because empty string always matches */ while ( (pos = str32str (pos, search)) && *nmatches < maximumNumberOfReplaces) { pos += len_search; (*nmatches) ++; } } } int64 len_replace = str32len (replace); int64 len_result = len_string + *nmatches * (len_replace - len_search); char32 *result = Melder_malloc (char32, (len_result + 1) * (int64) sizeof (char32)); result[len_result] = '\0'; const char32 *posp = pos = string; int nchar = 0, result_nchar = 0; for (long i = 1; i <= *nmatches; i++) { pos = str32str (pos, search); /* Copy gap between end of previous match and start of current. */ nchar = (pos - posp); if (nchar > 0) { str32ncpy (result + result_nchar, posp, nchar); result_nchar += nchar; } /* Insert the replace string in result. */ str32ncpy (result + result_nchar, replace, len_replace); result_nchar += len_replace; /* Next search starts after the match. */ pos += len_search; posp = pos; } /* Copy gap between end of match and end of string. */ pos = string + len_string; nchar = pos - posp; if (nchar > 0) { str32ncpy (result + result_nchar, posp, nchar); } return result; }
void structGraphicsScreen :: v_polyline (long numberOfPoints, double *xyDC, bool close) { #if cairo if (duringXor) { #if ALLOW_GDK_DRAWING gdkPrepareLine (this); for (long i = 0; i < numberOfPoints - 1; i ++) { gdk_draw_line (our d_window, our d_gdkGraphicsContext, xyDC [i + i], xyDC [i + i + 1], xyDC [i + i + 2], xyDC [i + i + 3]); } gdkRevertLine (this); gdk_flush (); #endif } else { if (our d_cairoGraphicsContext == NULL) return; cairoPrepareLine (this); // cairo_new_path (d_cairoGraphicsContext); // move_to() automatically creates a new path cairo_move_to (our d_cairoGraphicsContext, xyDC [0], xyDC [1]); for (long i = 1; i < numberOfPoints; i ++) { cairo_line_to (our d_cairoGraphicsContext, xyDC [i + i], xyDC [i + i + 1]); } if (close) cairo_close_path (our d_cairoGraphicsContext); cairo_stroke (our d_cairoGraphicsContext); cairoRevertLine (this); } #elif win winPrepareLine (this); POINT *points = Melder_malloc (POINT, numberOfPoints + close); if (points) { for (long i = 0; i < numberOfPoints; i ++) { points [i]. x = *xyDC, xyDC ++; points [i]. y = *xyDC, xyDC ++; } if (close) points [numberOfPoints] = points [0]; Polyline (our d_gdiGraphicsContext, points, numberOfPoints + close); if (our d_fatNonSolid) { for (long i = 0; i < numberOfPoints; i ++) points [i]. x -= 1; if (close) points [numberOfPoints] = points [0]; Polyline (our d_gdiGraphicsContext, points, numberOfPoints + close); for (long i = 0; i < numberOfPoints; i ++) { points [i]. x += 1; points [i]. y -= 1; } if (close) points [numberOfPoints] = points [0]; Polyline (our d_gdiGraphicsContext, points, numberOfPoints + close); } } DEFAULT #elif mac GraphicsQuartz_initDraw (this); quartzPrepareLine (this); CGContextBeginPath (our d_macGraphicsContext); CGContextMoveToPoint (our d_macGraphicsContext, xyDC [0], xyDC [1]); // starts a new subpath for (long i = 1; i < numberOfPoints; i ++) { CGContextAddLineToPoint (our d_macGraphicsContext, xyDC [i + i], xyDC [i + i + 1]); } if (close) CGContextClosePath (our d_macGraphicsContext); // closes only the subpath CGContextStrokePath (our d_macGraphicsContext); quartzRevertLine (this); GraphicsQuartz_exitDraw (this); #endif }