int main (int argc, char * argv[])
{
	// Plant frequencies... (zeroed here just to suppress a -Wall warning)
	float f_AA_MM = 0;
	float f_AA_Mm = 0;
	float f_AA_mm = 0;
	float f_Aa_MM = 0;
	float f_Aa_Mm = 0;
	float f_Aa_mm = 0;
	float f_aa_MM = 0;
	float f_aa_Mm = 0;
	float f_aa_mm = 0;

	float next_f_AA_MM;
	float next_f_AA_Mm;
	float next_f_AA_mm;
	float next_f_Aa_MM;
	float next_f_Aa_Mm;
	float next_f_Aa_mm;
	float next_f_aa_MM;
	float next_f_aa_Mm;
	float next_f_aa_mm;

	// Pollen frequencies...
	float p_A_M;
	float p_A_m;
	float p_a_M;
	float p_a_m;
	
	// Egg frequencies...
	float e_A_M;
	float e_A_m;
	float e_a_M;
	float e_a_m;
	
	float male = 0;
	float female = 0;
	float inconstant = 0;
	
	float PSatC;				// Pollen saturation point for cosex receivers
	
	float K;
	float k;
	
	float totalpollen;
	float totalplants;
	int n;
	int x;
	int y;
	
	char bmp_filename[1024];
	char txt_filename[1024];
	
	FILE * textfile = NULL;

	
	parsecommandline(argc, argv);
	
	result = malloc(subdivisions * sizeof(int*));
	if (result == NULL)
	{
		printf("Out of memory!\n");
		exit(1);
	}
	for (n = 0; n < subdivisions; n++)
	{
		result[n] = malloc(subdivisions * sizeof(int));
		if (result[n] == NULL)
		{
			printf("Out of memory!\n");
			exit(1);
		}
	}
	
	// Print all settings...
	
	printf("\nModel %d\n\n", MODEL);
	
	if (onerun)
	{
		printf("Q = %G (K = %G, pi = %G)\n", Q, (1 / Q) - 1, 1 / Q);
		printf("F = %G (k = %G, \"omega\" = %G)\n\n", F, (1 / F) - 1, 1 / F);
	}
	
	printf("h = %G\n", h);
	printf("Selfing rate = %G\n", S);
	printf("Inbreeding depression = %G\n", d);
	printf("YY viability = %G (YY penalty = %G)\n", V, 1 - V);
	printf("PSatF = %G\n\n", PSatF);
	
	printf("Iterations = %d\n\n", endpoint);
	
	if (onerun == 0)
	{
		printf("Warning: --onerun option not received, therefore program will\n");
		printf("use %d Q and F combinations and produce a graph. This may\n", subdivisions * subdivisions);
		printf("take a long time. If this was not your intention, terminate now.\n\n");
		
		printf("                       %d |\n", oldformat ? oldformatlimit : 1);
		printf("Output format:       %s   |\n", oldformat ? "k" : "F");
		printf("                       0 |\n");
		printf("                          -----\n");
		printf("                          0   %d\n", oldformat ? oldformatlimit : 1);
		printf("                            %s\n\n", oldformat ? "K" : "Q");
	}
	
	// Choose names for .bmp and .txt output files (if needed)...
	
	sprintf(bmp_filename, "model%d_start%s_V%G_S%G_d%G_h%G_PSatF%G_ppY%G.bmp", MODEL, pgd ? "PGD" : "DIO", V, S, d, h, PSatF, ppY);
	sprintf(txt_filename, "model%d_start%s_V%G_S%G_d%G_h%G_PSatF%G_ppY%G.txt", MODEL, pgd ? "PGD" : "DIO", V, S, d, h, PSatF, ppY);
	
	// Open .txt output file (if needed)...
	
	if (onerun == 0 && gnuplot)
	{
		textfile = fopen(txt_filename, "w");
	}
	
	
	for (y = 0; y < subdivisions; y++)
	{
		for (x = 0; x < subdivisions; x++)
		{
			if (onerun == 0)
			{
			
				// Here we map the X,Y coordinates of our output .bmp file onto Q and F parameters...
			
				if (oldformat == 0)
				{
					Q = (float) x / (subdivisions - 1);						// X axis: Q values 0 to 1
					F = (float) y / (subdivisions - 1);						// Y axis: F values 0 to 1
				} else {
					K = ((float) x / (subdivisions - 1)) * oldformatlimit;	// X axis: K values 0 to oldformatlimit
					k = ((float) y / (subdivisions - 1)) * oldformatlimit;	// Y axis: k values 0 to oldformatlimit
					
					// But Q and F are the parameters actually used by the code, so calculate them:
					Q = 1 / (1 + K);
					F = 1 / (1 + k);
				}
			}
	
			// Set start plant frequencies...
			
			if (pgd == 0)				// Start with DIOECY, try inconstant invasion
			{
				f_AA_MM = 0;
				f_AA_Mm = 0;
				f_AA_mm = 0.499;
				f_Aa_MM = 0;
				f_Aa_Mm = 0.002;
				f_Aa_mm = 0.499;
				f_aa_MM = 0;
				f_aa_Mm = 0;
				f_aa_mm = 0;
			} else {					// Start with PSEUDO-GYNODIOECY, try male invasion
				f_AA_MM = 0.499;
				f_AA_Mm = 0;
				f_AA_mm = 0;
				f_Aa_MM = 0.499;
				f_Aa_Mm = 0;
				f_Aa_mm = 0.002;
				f_aa_MM = 0;
				f_aa_Mm = 0;
				f_aa_mm = 0;
			}
	
			for (n = 0; n < endpoint; n++)
			{
				// Outcrossed pollen frequencies....................................................
				//
				// Here we sum up the 4 types of pollen (containing the 4 possible allele combinations)
				// from the various possible sources. We could do this in 4 equations (as in the paper)
				// but it's simpler to consider each source in turn and add to the totals.
				
				p_A_M = 0;
				p_A_m = 0;
				p_a_M = 0;
				p_a_m = 0;
				
				// From AA MM pure females (genotype 1)
				;
				
				// From AA Mm pure females (genotype 2)
				;
				
				// From AA mm pure females (genotype 3)
				;
				
				// From Aa MM inconstants (genotype 4) as cosexes
				p_A_M += f_Aa_MM * 0.5 * h * Q;
				p_a_M += f_Aa_MM * 0.5 * h * Q;
				
				// From Aa MM inconstants (genotype 4) as males
				p_A_M += f_Aa_MM * 0.5 * (1 - h);
				p_a_M += f_Aa_MM * 0.5 * (1 - h);
				
				// From Aa Mm inconstants (genotype 5) as cosexes
				p_A_M += f_Aa_Mm * 0.25 * h * Q;
				p_A_m += f_Aa_Mm * 0.25 * h * Q;
				p_a_M += f_Aa_Mm * 0.25 * h * Q;
				p_a_m += f_Aa_Mm * 0.25 * h * Q;
				
				// From Aa Mm inconstants (genotype 5) as males
				p_A_M += f_Aa_Mm * 0.25 * (1 - h);
				p_A_m += f_Aa_Mm * 0.25 * (1 - h);
				p_a_M += f_Aa_Mm * 0.25 * (1 - h);
				p_a_m += f_Aa_Mm * 0.25 * (1 - h);
				
				// From Aa mm pure males (genotype 6)
				p_A_m += f_Aa_mm * 0.5;
				p_a_m += f_Aa_mm * 0.5;
				
				// From aa MM inconstants (genotype 7) as cosexes
				p_a_M += f_aa_MM * h * Q;
				
				// From aa MM inconstants (genotype 7) as males
				p_a_M += f_aa_MM * (1 - h);
				
				// From aa Mm inconstants (genotype 8) as cosexes
				p_a_M += f_aa_Mm * 0.5 * h * Q;
				p_a_m += f_aa_Mm * 0.5 * h * Q;
				
				// From aa Mm inconstants (genotype 8) as males
				p_a_M += f_aa_Mm * 0.5 * (1 - h);
				p_a_m += f_aa_Mm * 0.5 * (1 - h);
				
				// From aa mm pure males (genotype 9)
				p_a_m += f_aa_mm;
				
				// Normalise pollen frequencies to add up to 1......................................
				
				totalpollen = p_A_M + p_A_m + p_a_M + p_a_m;
				if (totalpollen > 0)
				{
					p_A_M /= totalpollen;
					p_A_m /= totalpollen;
					p_a_M /= totalpollen;
					p_a_m /= totalpollen;
				}
				
				// Outcrossed egg frequencies.......................................................
				
				// Calculate pollen required to fertilise a cosex's outcrossing ovules:
				PSatC = PSatF * F * (1 - S);
				
				e_A_M = 0;
				e_A_m = 0;
				e_a_M = 0;
				e_a_m = 0;
				
				// From AA MM pure females (genotype 1)
				if (totalpollen >= PSatF)
				{
					e_A_M += f_AA_MM;
				} else {
					e_A_M += f_AA_MM * totalpollen / PSatF;
				}
				
				// From AA Mm pure females (genotype 2)
				if (totalpollen >= PSatF)
				{
					e_A_M += f_AA_Mm * 0.5;
					e_A_m += f_AA_Mm * 0.5;
				} else {
					e_A_M += f_AA_Mm * 0.5 * totalpollen / PSatF;
					e_A_m += f_AA_Mm * 0.5 * totalpollen / PSatF;
				}
				
				// From AA mm pure females (genotype 3)
				if (totalpollen >= PSatF)
				{
					e_A_m += f_AA_mm;
				} else {
					e_A_m += f_AA_mm * totalpollen / PSatF;
				}
				
				// From Aa MM inconstants (genotype 4) as cosexes
				if (totalpollen >= PSatC)
				{
					e_A_M += f_Aa_MM * h * 0.5 * (1 - S) * F;
					e_a_M += f_Aa_MM * h * 0.5 * (1 - S) * F;
				} else {
					e_A_M += f_Aa_MM * h * 0.5 * (1 - S) * F * totalpollen / PSatC;
					e_a_M += f_Aa_MM * h * 0.5 * (1 - S) * F * totalpollen / PSatC;
				}
				
				// From Aa Mm inconstants (genotype 5) as cosexes
				if (totalpollen >= PSatC)
				{
					e_A_M += f_Aa_Mm * h * 0.25 * (1 - S) * F;
					e_A_m += f_Aa_Mm * h * 0.25 * (1 - S) * F;
					e_a_M += f_Aa_Mm * h * 0.25 * (1 - S) * F;
					e_a_m += f_Aa_Mm * h * 0.25 * (1 - S) * F;
				} else {
					e_A_M += f_Aa_Mm * h * 0.25 * (1 - S) * F * totalpollen / PSatC;
					e_A_m += f_Aa_Mm * h * 0.25 * (1 - S) * F * totalpollen / PSatC;
					e_a_M += f_Aa_Mm * h * 0.25 * (1 - S) * F * totalpollen / PSatC;
					e_a_m += f_Aa_Mm * h * 0.25 * (1 - S) * F * totalpollen / PSatC;
				}
				
				// From Aa mm pure males (genotype 6)
				;
				
				// From aa MM inconstants (genotype 7) as cosexes
				if (totalpollen >= PSatC)
				{
					e_a_M += f_aa_MM * h * (1 - S) * F;
				} else {
					e_a_M += f_aa_MM * h * (1 - S) * F * totalpollen / PSatC;
				}
				
				// From aa Mm inconstants (genotype 8) as cosexes
				if (totalpollen >= PSatC)
				{
					e_a_M += f_aa_Mm * h * 0.5 * (1 - S) * F;
					e_a_m += f_aa_Mm * h * 0.5 * (1 - S) * F;
				} else {
					e_a_M += f_aa_Mm * h * 0.5 * (1 - S) * F * totalpollen / PSatC;
					e_a_m += f_aa_Mm * h * 0.5 * (1 - S) * F * totalpollen / PSatC;
				}
				
				// From aa mm pure males (genotype 9)
				;
				
				// WE CANNOT AND MUST NOT NORMALISE THE EGG FREQUENCIES, AS WE HAVEN'T
				// YET CONSIDERED THE SELFED EGGS. BUT WE DON'T NEED TO NORMALISE.
				
				// Plant frequencies from outcrossing...............................................
				
				next_f_AA_MM = p_A_M * e_A_M;
				next_f_AA_Mm = p_A_M * e_A_m + p_A_m * e_A_M;
				next_f_AA_mm = p_A_m * e_A_m;
				next_f_Aa_MM = p_A_M * e_a_M + p_a_M * e_A_M;
				next_f_Aa_Mm = p_A_M * e_a_m + p_A_m * e_a_M + p_a_M * e_A_m + p_a_m * e_A_M;
				next_f_Aa_mm = p_A_m * e_a_m + p_a_m * e_A_m;
				next_f_aa_MM = p_a_M * e_a_M;
				next_f_aa_Mm = p_a_M * e_a_m + p_a_m * e_a_M;
				next_f_aa_mm = p_a_m * e_a_m;
				
				// Additional plants from selfing...................................................
				
				// From AA MM pure females (genotype 1)
				;
				
				// From AA Mm pure females (genotype 2)
				;
				
				// From AA mm pure females (genotype 3)
				;
				
				// From Aa MM inconstants (genotype 4)
				next_f_AA_MM += f_Aa_MM * 0.25 * S * (1 - d) * h * F;
				next_f_Aa_MM += f_Aa_MM * 0.5 * S * (1 - d) * h * F;
				next_f_aa_MM += f_Aa_MM * 0.25 * S * (1 - d) * h * F;
				
				// From Aa Mm inconstants (genotype 5)
				next_f_AA_MM += f_Aa_Mm * 0.0625 * S * (1 - d) * h * F;
				next_f_AA_Mm += f_Aa_Mm * 0.125 * S * (1 - d) * h * F;
				next_f_AA_mm += f_Aa_Mm * 0.0625 * S * (1 - d) * h * F;
				next_f_Aa_MM += f_Aa_Mm * 0.125 * S * (1 - d) * h * F;
				next_f_Aa_Mm += f_Aa_Mm * 0.25 * S * (1 - d) * h * F;
				next_f_Aa_mm += f_Aa_Mm * 0.125 * S * (1 - d) * h * F;
				next_f_aa_MM += f_Aa_Mm * 0.0625 * S * (1 - d) * h * F;
				next_f_aa_Mm += f_Aa_Mm * 0.125 * S * (1 - d) * h * F;
				next_f_aa_mm += f_Aa_Mm * 0.0625 * S * (1 - d) * h * F;
				
				// From Aa mm pure males (genotype 6)
				;
				
				// From aa MM inconstants (genotype 7)
				next_f_aa_MM += f_aa_MM * S * (1 - d) * h * F;
				
				// From aa Mm inconstants (genotype 8)
				next_f_aa_MM += f_aa_Mm * 0.25 * S * (1 - d) * h * F;
				next_f_aa_Mm += f_aa_Mm * 0.5 * S * (1 - d) * h * F;
				next_f_aa_mm += f_aa_Mm * 0.25 * S * (1 - d) * h * F;
				
				// From aa mm pure males (genotype 9)
				;

				// Apply YY penalty.................................................................
				
				next_f_aa_MM *= V;
				next_f_aa_Mm *= V;
				next_f_aa_mm *= V;
				
				// Copy.............................................................................
				
				f_AA_MM = next_f_AA_MM;
				f_AA_Mm = next_f_AA_Mm;
				f_AA_mm = next_f_AA_mm;
				f_Aa_MM = next_f_Aa_MM;
				f_Aa_Mm = next_f_Aa_Mm;
				f_Aa_mm = next_f_Aa_mm;
				f_aa_MM = next_f_aa_MM;
				f_aa_Mm = next_f_aa_Mm;
				f_aa_mm = next_f_aa_mm;
			
				// Normalise plant frequencies to add up to 1.......................................
				
				totalplants = f_AA_MM + f_AA_Mm + f_AA_mm + f_Aa_MM + f_Aa_Mm + f_Aa_mm + f_aa_MM + f_aa_Mm + f_aa_mm;
				if (totalplants > 0)
				{
					f_AA_MM /= totalplants;
					f_AA_Mm /= totalplants;
					f_AA_mm /= totalplants;
					f_Aa_MM /= totalplants;
					f_Aa_Mm /= totalplants;
					f_Aa_mm /= totalplants;
					f_aa_MM /= totalplants;
					f_aa_Mm /= totalplants;
					f_aa_mm /= totalplants;
				}
			}
	
			// Calculate and save results...
			
			female = f_AA_MM + f_AA_Mm + f_AA_mm;
			male = f_Aa_mm + f_aa_mm;
			inconstant = f_Aa_MM + f_Aa_Mm + f_aa_MM + f_aa_Mm;
			
			if (male > threshold && female > threshold && inconstant > threshold)
			{
				result[x][y] = SSD;
			} else if (male > threshold && female > threshold) {
				result[x][y] = DIO;
			} else if (female > threshold && inconstant > threshold) {
				result[x][y] = PGD;
			} else if (male > threshold && inconstant > threshold) {
				result[x][y] = PAD;
			} else if (inconstant > threshold) {
				result[x][y] = INC;
			} else {
				result[x][y] = 0;
			}
			
			if (onerun == 0 && gnuplot)
			{
				fprintf(textfile, "%f", female);
				if (x == subdivisions - 1)
				{
					fprintf(textfile, "\n");
				} else {
					fprintf(textfile, "\t");
				}
			}
			
			if (onerun) break;
		}
		if (onerun) break;
	}
	
	if (onerun == 0)
	{
		drawbmp(bmp_filename, 1);
		printf("Saved %s\n", bmp_filename);
	} else {
		printf("Females       Males         Inconstants\n");
		printf("%.6f      %.6f      %.6f\n\n", female, male, inconstant);

		printf("Genotype frequencies, as notated by E&B (2007), or C&C (2012):\n\n");
		
		printf("E&B:  AA MM     AA Mm     AA mm     Aa MM     Aa Mm     Aa mm     aa MM     aa Mm     aa mm\n");
		printf("C&C:  mm AA     mm Aa     mm aa     Mm AA     Mm Aa     Mm aa     MM AA     MM Aa     MM aa\n");
		printf("      %.6f  %.6f  %.6f  %.6f  %.6f  %.6f  %.6f  %.6f  %.6f\n\n", f_AA_MM, f_AA_Mm, f_AA_mm, f_Aa_MM, f_Aa_Mm, f_Aa_mm, f_aa_MM, f_aa_Mm, f_aa_mm);
		
		if (male > threshold && female > threshold && inconstant > threshold)
		{
			printf("Final state: SSD\n");
		} else if (male > threshold && female > threshold) {
			printf("Final state: DIO\n");
		} else if (female > threshold && inconstant > threshold) {
			printf("Final state: PGD\n");
		} else if (male > threshold && inconstant > threshold) {
			printf("Final state: PAD\n");
		} else if (inconstant > threshold) {
			printf("Final state: INC\n");
		} else {
			printf("Final state: ???\n");
		}
	}
	
	return 0;
}
示例#2
0
static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
{
	fz_page *page;
	fz_display_list *list = NULL;
	fz_device *dev = NULL;
	int start;
	fz_cookie cookie = { 0 };
	int needshot = 0;

	fz_var(list);
	fz_var(dev);

	if (showtime)
	{
		start = gettime();
	}

	fz_try(ctx)
	{
		page = fz_load_page(doc, pagenum - 1);
	}
	fz_catch(ctx)
	{
		fz_throw(ctx, "cannot load page %d in file '%s'", pagenum, filename);
	}

	if (mujstest_file)
	{
		fz_interactive *inter = fz_interact(doc);
		fz_widget *widget = NULL;

		if (inter)
			widget = fz_first_widget(inter, page);

		if (widget)
		{
			fprintf(mujstest_file, "GOTO %d\n", pagenum);
			needshot = 1;
		}
		for (;widget; widget = fz_next_widget(inter, widget))
		{
			fz_rect rect = fz_widget_bbox(widget);
			int w = (rect.x1-rect.x0);
			int h = (rect.y1-rect.y0);
			int len;
			int type = fz_widget_get_type(widget);

			++mujstest_count;
			switch (type)
			{
			default:
				fprintf(mujstest_file, "%% UNKNOWN %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1);
				break;
			case FZ_WIDGET_TYPE_PUSHBUTTON:
				fprintf(mujstest_file, "%% PUSHBUTTON %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1);
				break;
			case FZ_WIDGET_TYPE_CHECKBOX:
				fprintf(mujstest_file, "%% CHECKBOX %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1);
				break;
			case FZ_WIDGET_TYPE_RADIOBUTTON:
				fprintf(mujstest_file, "%% RADIOBUTTON %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1);
				break;
			case FZ_WIDGET_TYPE_TEXT:
			{
				int maxlen = fz_text_widget_max_len(inter, widget);
				int texttype = fz_text_widget_content_type(inter, widget);

				/* If height is low, assume a single row, and base
				 * the width off that. */
				if (h < 10)
				{
					w = (w+h-1) / (h ? h : 1);
					h = 1;
				}
				/* Otherwise, if width is low, work off height */
				else if (w < 10)
				{
					h = (w+h-1) / (w ? w : 1);
					w = 1;
				}
				else
				{
					w = (w+9)/10;
					h = (h+9)/10;
				}
				len = w*h;
				if (len < 2)
					len = 2;
				if (len > maxlen)
					len = maxlen;
				fprintf(mujstest_file, "%% TEXT %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1);
				switch (texttype)
				{
				default:
				case FZ_WIDGET_CONTENT_UNRESTRAINED:
					fprintf(mujstest_file, "TEXT %d ", mujstest_count);
					escape_string(mujstest_file, len-3, lorem);
					fprintf(mujstest_file, "\n");
					break;
				case FZ_WIDGET_CONTENT_NUMBER:
					fprintf(mujstest_file, "TEXT %d\n", mujstest_count);
					break;
				case FZ_WIDGET_CONTENT_SPECIAL:
					fprintf(mujstest_file, "TEXT %lld\n", 46702919800LL + mujstest_count);
					break;
				case FZ_WIDGET_CONTENT_DATE:
					fprintf(mujstest_file, "TEXT Jun %d 1979\n", 1 + ((13 + mujstest_count) % 30));
					break;
				case FZ_WIDGET_CONTENT_TIME:
					++mujstest_count;
					fprintf(mujstest_file, "TEXT %02d:%02d\n", ((mujstest_count/60) % 24), mujstest_count % 60);
					break;
				}
				break;
			}
			case FZ_WIDGET_TYPE_LISTBOX:
				fprintf(mujstest_file, "%% LISTBOX %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1);
				break;
			case FZ_WIDGET_TYPE_COMBOBOX:
				fprintf(mujstest_file, "%% COMBOBOX %0.2f %0.2f %0.2f %0.2f\n", rect.x0, rect.y0, rect.x1, rect.y1);
				break;
			}
			fprintf(mujstest_file, "CLICK %0.2f %0.2f\n", (rect.x0+rect.x1)/2, (rect.y0+rect.y1)/2);
		}
	}

	if (uselist)
	{
		fz_try(ctx)
		{
			list = fz_new_display_list(ctx);
			dev = fz_new_list_device(ctx, list);
			fz_run_page(doc, page, dev, fz_identity, &cookie);
		}
		fz_always(ctx)
		{
			fz_free_device(dev);
			dev = NULL;
		}
		fz_catch(ctx)
		{
			fz_free_display_list(ctx, list);
			fz_free_page(doc, page);
			fz_throw(ctx, "cannot draw page %d in file '%s'", pagenum, filename);
		}
	}

	if (showxml)
	{
		fz_try(ctx)
		{
			dev = fz_new_trace_device(ctx);
			fz_printf(out, "<page number=\"%d\">\n", pagenum);
			if (list)
				fz_run_display_list(list, dev, fz_identity, fz_infinite_rect, &cookie);
			else
				fz_run_page(doc, page, dev, fz_identity, &cookie);
			fz_printf(out, "</page>\n");
		}
		fz_always(ctx)
		{
			fz_free_device(dev);
			dev = NULL;
		}
		fz_catch(ctx)
		{
			fz_free_display_list(ctx, list);
			fz_free_page(doc, page);
			fz_rethrow(ctx);
		}
	}

	if (showtext)
	{
		fz_text_page *text = NULL;

		fz_var(text);

		fz_try(ctx)
		{
			text = fz_new_text_page(ctx, fz_bound_page(doc, page));
			dev = fz_new_text_device(ctx, sheet, text);
			if (list)
				fz_run_display_list(list, dev, fz_identity, fz_infinite_rect, &cookie);
			else
				fz_run_page(doc, page, dev, fz_identity, &cookie);
			fz_free_device(dev);
			dev = NULL;
			if (showtext == TEXT_XML)
			{
				fz_print_text_page_xml(ctx, out, text);
			}
			else if (showtext == TEXT_HTML)
			{
				fz_print_text_page_html(ctx, out, text);
			}
			else if (showtext == TEXT_PLAIN)
			{
				fz_print_text_page(ctx, out, text);
				fz_printf(out, "\f\n");
			}
		}
		fz_always(ctx)
		{
			fz_free_device(dev);
			dev = NULL;
			fz_free_text_page(ctx, text);
		}
		fz_catch(ctx)
		{
			fz_free_display_list(ctx, list);
			fz_free_page(doc, page);
			fz_rethrow(ctx);
		}
	}

	if (showmd5 || showtime)
		printf("page %s %d", filename, pagenum);

#ifdef GDI_PLUS_BMP_RENDERER
	// hack: use -G0 to "enable GDI+" when saving as TGA
	if (output && (strstr(output, ".bmp") || strstr(output, ".tga") && !gamma_value))
		drawbmp(ctx, doc, page, list, pagenum);
	else
#endif
	if (output || showmd5 || showtime)
	{
		float zoom;
		fz_matrix ctm;
		fz_rect bounds, tbounds;
		fz_bbox ibounds;
		fz_pixmap *pix = NULL;
		int w, h;

		fz_var(pix);

		bounds = fz_bound_page(doc, page);
		zoom = resolution / 72;
		ctm = fz_scale(zoom, zoom);
		ctm = fz_concat(ctm, fz_rotate(rotation));
		tbounds = fz_transform_rect(ctm, bounds);
		ibounds = fz_round_rect(tbounds); /* convert to integers */

		/* Make local copies of our width/height */
		w = width;
		h = height;

		/* If a resolution is specified, check to see whether w/h are
		 * exceeded; if not, unset them. */
		if (res_specified)
		{
			int t;
			t = ibounds.x1 - ibounds.x0;
			if (w && t <= w)
				w = 0;
			t = ibounds.y1 - ibounds.y0;
			if (h && t <= h)
				h = 0;
		}

		/* Now w or h will be 0 unless they need to be enforced. */
		if (w || h)
		{
			float scalex = w / (tbounds.x1 - tbounds.x0);
			float scaley = h / (tbounds.y1 - tbounds.y0);

			if (fit)
			{
				if (w == 0)
					scalex = 1.0f;
				if (h == 0)
					scaley = 1.0f;
			}
			else
			{
				if (w == 0)
					scalex = scaley;
				if (h == 0)
					scaley = scalex;
			}
			if (!fit)
			{
				if (scalex > scaley)
					scalex = scaley;
				else
					scaley = scalex;
			}
			ctm = fz_concat(ctm, fz_scale(scalex, scaley));
			tbounds = fz_transform_rect(ctm, bounds);
		}
		ibounds = fz_round_rect(tbounds);

		/* TODO: banded rendering and multi-page ppm */

		fz_try(ctx)
		{
			pix = fz_new_pixmap_with_bbox(ctx, colorspace, ibounds);

			if (savealpha)
				fz_clear_pixmap(ctx, pix);
			else
				fz_clear_pixmap_with_value(ctx, pix, 255);

			dev = fz_new_draw_device(ctx, pix);
			if (list)
				fz_run_display_list(list, dev, ctm, tbounds, &cookie);
			else
				fz_run_page(doc, page, dev, ctm, &cookie);
			fz_free_device(dev);
			dev = NULL;

			if (invert)
				fz_invert_pixmap(ctx, pix);
			if (gamma_value != 1)
				fz_gamma_pixmap(ctx, pix, gamma_value);

			if (savealpha)
				fz_unmultiply_pixmap(ctx, pix);

			if (output)
			{
				char buf[512];
				sprintf(buf, output, pagenum);
				if (strstr(output, ".pgm") || strstr(output, ".ppm") || strstr(output, ".pnm"))
					fz_write_pnm(ctx, pix, buf);
				else if (strstr(output, ".pam"))
					fz_write_pam(ctx, pix, buf, savealpha);
				else if (strstr(output, ".png"))
					fz_write_png(ctx, pix, buf, savealpha);
				else if (strstr(output, ".pbm")) {
					fz_bitmap *bit = fz_halftone_pixmap(ctx, pix, NULL);
					fz_write_pbm(ctx, bit, buf);
					fz_drop_bitmap(ctx, bit);
				}
				/* SumatraPDF: support TGA as output format */
				else if (strstr(output, ".tga"))
					fz_write_tga(ctx, pix, buf, savealpha);
			}

			if (showmd5)
			{
				unsigned char digest[16];
				int i;

				fz_md5_pixmap(pix, digest);
				printf(" ");
				for (i = 0; i < 16; i++)
					printf("%02x", digest[i]);
			}
		}
		fz_always(ctx)
		{
			fz_free_device(dev);
			dev = NULL;
			fz_drop_pixmap(ctx, pix);
		}
		fz_catch(ctx)
		{
			fz_free_display_list(ctx, list);
			fz_free_page(doc, page);
			fz_rethrow(ctx);
		}
	}
示例#3
0
int main (int argc, char * argv[]) {

    int i, j, n;                          // General purpose counters
    double x, y;                          // Source coordinates of particle being tracked
    int source_column, source_row;                // Source grid location
    double r, s, nextr, nexts;            // Values as particle is iterated through the Mandelbrot function
    double x_jump, y_jump;                        // Distances between particles in the source grid
    double target_startx, target_starty;  // Top-left coordinates of drawn area
    double target_endx, target_endy;      // Bottom-right coordinates of drawn area
    double pixel_width;                   // Actual distance represented by a pixel in the drawn area

    char filename[200];


    for (i = 0; i < WIDTH; i++)
    {
        for (j = 0; j < HEIGHT; j++)
        {
            redcount[i][j] = 0;
            greencount[i][j] = 0;
            bluecount[i][j] = 0;
        }
    }

    /*
    target_startx = CENTRE_X - ((double) WIDTH / (ZOOM * 2));
    target_endx = CENTRE_X + ((double) WIDTH / (ZOOM * 2));

    target_starty = CENTRE_Y - ((double) HEIGHT / (ZOOM * 2));
    target_endy = CENTRE_Y + ((double) HEIGHT / (ZOOM * 2));

    pixel_width = (target_endx - target_startx) / WIDTH;

    x_jump = ((double) SOURCE_RIGHT_X - SOURCE_LEFT_X) / SOURCE_COLUMNS;
    y_jump = ((double) SOURCE_BOTTOM_Y - SOURCE_TOP_Y) / SOURCE_ROWS;
    */

    // Map Source (world space) to Pixels (image space)
    double world_2_image_x = (double)(WIDTH -1) / ((double) SOURCE_RIGHT_X - SOURCE_LEFT_X);
    double world_2_image_y = (double)(HEIGHT-1) / ((double) SOURCE_BOTTOM_Y - SOURCE_TOP_Y);

    x_jump = ((double) SOURCE_RIGHT_X - SOURCE_LEFT_X) / (SOURCE_COLUMNS - 1);
    y_jump = ((double) SOURCE_BOTTOM_Y - SOURCE_TOP_Y) / (SOURCE_ROWS    - 1);

    iterations = RED_ITERATIONS_UPPER;
    if (GREEN_ITERATIONS_UPPER > iterations) iterations = GREEN_ITERATIONS_UPPER;
    if (BLUE_ITERATIONS_UPPER > iterations) iterations = BLUE_ITERATIONS_UPPER;

    // Main bit...

    //x = SOURCE_LEFT_X;
    //for (source_column = 0; source_column < SOURCE_COLUMNS; source_column++, x += x_jump)
    //{
    //        y = SOURCE_TOP_Y;
    //        for (source_row = 0; source_row < SOURCE_ROWS; source_row++, y += y_jump)
    double x0;
    source_column = 0;
    for( x0 = SOURCE_LEFT_X; x0 < SOURCE_RIGHT_X; source_column++, x0 += x_jump )
    {
        double y0;
        for( y0 = SOURCE_TOP_Y; y0 < SOURCE_BOTTOM_Y; y0 += y_jump )
        {

#ifdef OPTIMISE
            if
            (
                (x >  -1.2 && x <=  -1.1 && y >  -0.1 && y < 0.1)
                || (x >  -1.1 && x <=  -0.9 && y >  -0.2 && y < 0.2)
                || (x >  -0.9 && x <=  -0.8 && y >  -0.1 && y < 0.1)
                || (x > -0.69 && x <= -0.61 && y >  -0.2 && y < 0.2)
                || (x > -0.61 && x <=  -0.5 && y > -0.37 && y < 0.37)
                || (x >  -0.5 && x <= -0.39 && y > -0.48 && y < 0.48)
                || (x > -0.39 && x <=  0.14 && y > -0.55 && y < 0.55)
                || (x >  0.14 && x <   0.29 && y > -0.42 && y < -0.07)
                || (x >  0.14 && x <   0.29 && y >  0.07 && y < 0.42)
            ) continue;
#endif
            r = 0;
            s = 0;
            for (n = 0; n <= iterations; n++)
            {
                nextr = ((r * r) - (s * s)) + x;
                nexts = (2 * r * s) + y;
                r = nextr;
                s = nexts;
                if (n == iterations)
                {
                    // drawpath(x, y, target_startx, target_starty, pixel_width);
                    break;
                } else if ((r * r) + (s * s) > 4) {
                    //drawpath(x, y, target_startx, target_starty, pixel_width);
                    drawpath(x, y, world_2_image_x, world_2_image_y);
                    break;
                }
            }

        }

        if (source_column % UPDATETICK == 0)
        {
            printf("Reached source column: %d of %d\n", source_column, SOURCE_COLUMNS);
        }

    }

    sprintf(filename, "%s r %d g %d b %d spp %d.bmp", OUTFILE, RED_ITERATIONS_UPPER, GREEN_ITERATIONS_UPPER, BLUE_ITERATIONS_UPPER, (SOURCE_COLUMNS / WIDTH) * (SOURCE_ROWS / HEIGHT));
    drawbmp(filename);

    printf("Done.\n");
    return 0;
}