mirror of
				https://github.com/kolunmi/dwlb.git
				synced 2025-10-31 04:04:13 +00:00 
			
		
		
		
	optimize drawing routines
This commit is contained in:
		
							parent
							
								
									38fcc46115
								
							
						
					
					
						commit
						729304fb1f
					
				
							
								
								
									
										164
									
								
								dwlb.c
									
									
									
									
									
								
							
							
						
						
									
										164
									
								
								dwlb.c
									
									
									
									
									
								
							| @ -226,47 +226,48 @@ draw_text(char *text, | |||||||
| 	  pixman_image_t *background, | 	  pixman_image_t *background, | ||||||
| 	  pixman_color_t *fgcolor, | 	  pixman_color_t *fgcolor, | ||||||
| 	  pixman_color_t *bgcolor, | 	  pixman_color_t *bgcolor, | ||||||
| 	  uint32_t surface_width, | 	  uint32_t maxxpos, | ||||||
| 	  uint32_t height, | 	  uint32_t bufheight, | ||||||
| 	  uint32_t padding, | 	  uint32_t padding, | ||||||
| 	  bool commands) | 	  bool commands) | ||||||
| { | { | ||||||
| 	uint32_t codepoint; | 	if (!*text || !maxxpos) | ||||||
| 	uint32_t state = UTF8_ACCEPT; |  | ||||||
| 	uint32_t ixpos = xpos; |  | ||||||
| 	uint32_t nxpos; |  | ||||||
| 	uint32_t lastcp = 0; |  | ||||||
| 
 |  | ||||||
| 	if (!*text || !surface_width || xpos >= surface_width) |  | ||||||
| 		return xpos; | 		return xpos; | ||||||
| 
 | 
 | ||||||
| 	if ((nxpos = xpos + padding) > surface_width) | 	uint32_t ixpos = xpos; | ||||||
|  | 	uint32_t nxpos; | ||||||
|  | 
 | ||||||
|  | 	if ((nxpos = xpos + padding) + padding >= maxxpos) | ||||||
| 		return xpos; | 		return xpos; | ||||||
| 	xpos = nxpos; | 	xpos = nxpos; | ||||||
| 
 | 
 | ||||||
| 	pixman_color_t cur_fgcolor = *fgcolor; | 	bool drawfg = foreground && fgcolor; | ||||||
| 	pixman_color_t cur_bgcolor; | 	bool drawbg = background && bgcolor; | ||||||
| 	if (background && bgcolor) { |  | ||||||
| 		cur_bgcolor = *bgcolor; |  | ||||||
| 		pixman_image_fill_boxes(PIXMAN_OP_OVER, background, |  | ||||||
| 					&cur_bgcolor, 1, &(pixman_box32_t){ |  | ||||||
| 						.x1 = ixpos, |  | ||||||
| 						.x2 = xpos, |  | ||||||
| 						.y1 = 0, |  | ||||||
| 						.y2 = height |  | ||||||
| 					}); |  | ||||||
| 	} |  | ||||||
| 	 | 	 | ||||||
| 	pixman_image_t *fgfill = pixman_image_create_solid_fill(fgcolor); | 	pixman_image_t *fgfill; | ||||||
|  | 	pixman_color_t cur_fgcolor; | ||||||
|  | 	pixman_color_t cur_bgcolor; | ||||||
|  | 	if (drawfg) { | ||||||
|  | 		fgfill = pixman_image_create_solid_fill(fgcolor); | ||||||
|  | 		cur_fgcolor = *fgcolor; | ||||||
|  | 	} | ||||||
|  | 	if (drawbg) | ||||||
|  | 		cur_bgcolor = *bgcolor; | ||||||
|  | 
 | ||||||
|  | 	uint32_t codepoint; | ||||||
|  | 	uint32_t state = UTF8_ACCEPT; | ||||||
|  | 	uint32_t lastcp = 0; | ||||||
| 	 | 	 | ||||||
| 	for (char *p = text; *p; p++) { | 	for (char *p = text; *p; p++) { | ||||||
| 		/* Check for inline ^ commands */ | 		/* If commands are enabled, check for inline ^ commands */ | ||||||
| 		if (commands && state == UTF8_ACCEPT && *p == '^') { | 		if (commands && state == UTF8_ACCEPT && *p == '^') { | ||||||
| 			p++; | 			p++; | ||||||
| 			if (*p != '^') { | 			if (*p != '^') { | ||||||
| 				p = handle_cmd(p, &cur_fgcolor, &cur_bgcolor, fgcolor, bgcolor); | 				p = handle_cmd(p, &cur_fgcolor, &cur_bgcolor, fgcolor, bgcolor); | ||||||
|  | 				if (drawfg) { | ||||||
| 					pixman_image_unref(fgfill); | 					pixman_image_unref(fgfill); | ||||||
| 					fgfill = pixman_image_create_solid_fill(&cur_fgcolor); | 					fgfill = pixman_image_create_solid_fill(&cur_fgcolor); | ||||||
|  | 				} | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @ -285,11 +286,12 @@ draw_text(char *text, | |||||||
| 		long x_kern = 0; | 		long x_kern = 0; | ||||||
| 		if (lastcp) | 		if (lastcp) | ||||||
| 			fcft_kerning(font, lastcp, codepoint, &x_kern, NULL); | 			fcft_kerning(font, lastcp, codepoint, &x_kern, NULL); | ||||||
| 		if ((nxpos = xpos + x_kern + glyph->advance.x) > surface_width) | 		if ((nxpos = xpos + x_kern + glyph->advance.x) + padding > maxxpos) | ||||||
| 			break; | 			break; | ||||||
| 		xpos += x_kern; |  | ||||||
| 		lastcp = codepoint; | 		lastcp = codepoint; | ||||||
|  | 		xpos += x_kern; | ||||||
| 
 | 
 | ||||||
|  | 		if (drawfg) { | ||||||
| 			/* Detect and handle pre-rendered glyphs (e.g. emoji) */ | 			/* Detect and handle pre-rendered glyphs (e.g. emoji) */ | ||||||
| 			if (pixman_image_get_format(glyph->pix) == PIXMAN_a8r8g8b8) { | 			if (pixman_image_get_format(glyph->pix) == PIXMAN_a8r8g8b8) { | ||||||
| 				/* Only the alpha channel of the mask is used, so we can
 | 				/* Only the alpha channel of the mask is used, so we can
 | ||||||
| @ -306,41 +308,48 @@ draw_text(char *text, | |||||||
| 					PIXMAN_OP_OVER, fgfill, glyph->pix, foreground, 0, 0, 0, 0, | 					PIXMAN_OP_OVER, fgfill, glyph->pix, foreground, 0, 0, 0, 0, | ||||||
| 					xpos + glyph->x, ypos - glyph->y, glyph->width, glyph->height); | 					xpos + glyph->x, ypos - glyph->y, glyph->width, glyph->height); | ||||||
| 			} | 			} | ||||||
|  | 		} | ||||||
| 		 | 		 | ||||||
| 		if (background && bgcolor) | 		if (drawbg) | ||||||
| 			pixman_image_fill_boxes(PIXMAN_OP_OVER, background, | 			pixman_image_fill_boxes(PIXMAN_OP_OVER, background, | ||||||
| 						&cur_bgcolor, 1, &(pixman_box32_t){ | 						&cur_bgcolor, 1, &(pixman_box32_t){ | ||||||
| 							.x1 = xpos, | 							.x1 = xpos, .x2 = nxpos, | ||||||
| 							.x2 = nxpos, | 							.y1 = 0, .y2 = bufheight | ||||||
| 							.y1 = 0, |  | ||||||
| 							.y2 = height |  | ||||||
| 						}); | 						}); | ||||||
| 		 | 		 | ||||||
| 		/* increment pen position */ | 		/* increment pen position */ | ||||||
| 		xpos = nxpos; | 		xpos = nxpos; | ||||||
| 		ypos += glyph->advance.y; | 		ypos += glyph->advance.y; | ||||||
| 	} | 	} | ||||||
|  | 	if (drawfg) | ||||||
|  | 		pixman_image_unref(fgfill); | ||||||
| 
 | 
 | ||||||
|  | 	if (!lastcp) | ||||||
|  | 		return ixpos; | ||||||
| 	if (state != UTF8_ACCEPT) | 	if (state != UTF8_ACCEPT) | ||||||
| 		fprintf(stderr, "malformed UTF-8 sequence\n"); | 		fprintf(stderr, "malformed UTF-8 sequence\n"); | ||||||
| 	 | 	 | ||||||
| 	nxpos = MIN(xpos + padding, surface_width); | 	nxpos = xpos + padding; | ||||||
| 
 | 	if (drawbg) { | ||||||
| 	if (background && bgcolor) | 		/* Fill padding background */ | ||||||
|  | 		pixman_image_fill_boxes(PIXMAN_OP_OVER, background, | ||||||
|  | 					&cur_bgcolor, 1, &(pixman_box32_t){ | ||||||
|  | 						.x1 = ixpos, .x2 = ixpos + padding, | ||||||
|  | 						.y1 = 0, .y2 = bufheight | ||||||
|  | 					}); | ||||||
| 		pixman_image_fill_boxes(PIXMAN_OP_OVER, background, | 		pixman_image_fill_boxes(PIXMAN_OP_OVER, background, | ||||||
| 					bgcolor, 1, &(pixman_box32_t){ | 					bgcolor, 1, &(pixman_box32_t){ | ||||||
| 						.x1 = xpos, | 						.x1 = xpos, .x2 = nxpos, | ||||||
| 						.x2 = nxpos, | 						.y1 = 0, .y2 = bufheight | ||||||
| 						.y1 = 0, |  | ||||||
| 						.y2 = height |  | ||||||
| 					}); | 					}); | ||||||
| 	xpos = nxpos; |  | ||||||
| 	 |  | ||||||
| 	pixman_image_unref(fgfill); |  | ||||||
| 
 |  | ||||||
| 	return xpos; |  | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
|  | 	return nxpos; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #define TEXT_WIDTH(text, maxxpos, padding, commands)	\ | ||||||
|  | 	draw_text(text, 0, 0, NULL, NULL, NULL, NULL, maxxpos, 0, padding, commands) | ||||||
|  | 
 | ||||||
| static int | static int | ||||||
| draw_frame(Bar *b) | draw_frame(Bar *b) | ||||||
| { | { | ||||||
| @ -364,20 +373,12 @@ draw_frame(Bar *b) | |||||||
| 	/* Pixman image corresponding to main buffer */ | 	/* Pixman image corresponding to main buffer */ | ||||||
| 	pixman_image_t *bar = pixman_image_create_bits(PIXMAN_a8r8g8b8, b->width, b->height, data, b->width * 4); | 	pixman_image_t *bar = pixman_image_create_bits(PIXMAN_a8r8g8b8, b->width, b->height, data, b->width * 4); | ||||||
| 	 | 	 | ||||||
| 	/* Fill bar with background color */ |  | ||||||
| 	pixman_image_fill_boxes(PIXMAN_OP_SRC, bar, b->selmon ? &activecolor : &inactivecolor, 1, |  | ||||||
| 				&(pixman_box32_t) {.x1 = 0, .x2 = b->width, .y1 = 0, .y2 = b->height}); |  | ||||||
| 	 |  | ||||||
| 	/* Text background and foreground layers */ | 	/* Text background and foreground layers */ | ||||||
| 	pixman_image_t *background_left = pixman_image_create_bits(PIXMAN_a8r8g8b8, b->width, b->height, NULL, b->width * 4); | 	pixman_image_t *foreground = pixman_image_create_bits(PIXMAN_a8r8g8b8, b->width, b->height, NULL, b->width * 4); | ||||||
| 	pixman_image_t *foreground_left = pixman_image_create_bits(PIXMAN_a8r8g8b8, b->width, b->height, NULL, b->width * 4); | 	pixman_image_t *background = pixman_image_create_bits(PIXMAN_a8r8g8b8, b->width, b->height, NULL, b->width * 4); | ||||||
| 	pixman_image_t *background_right = pixman_image_create_bits(PIXMAN_a8r8g8b8, b->width, b->height, NULL, b->width * 4); |  | ||||||
| 	pixman_image_t *foreground_right = pixman_image_create_bits(PIXMAN_a8r8g8b8, b->width, b->height, NULL, b->width * 4); |  | ||||||
| 	pixman_image_t *foreground_title = pixman_image_create_bits(PIXMAN_a8r8g8b8, b->width, b->height, NULL, b->width * 4); |  | ||||||
| 	 | 	 | ||||||
| 	/* Draw on images */ | 	/* Draw on images */ | ||||||
| 	uint32_t xpos_left = 0; | 	uint32_t xpos_left = 0; | ||||||
| 	uint32_t xpos_right; |  | ||||||
| 	uint32_t ypos = (b->height + font->ascent - font->descent) / 2; | 	uint32_t ypos = (b->height + font->ascent - font->descent) / 2; | ||||||
| 
 | 
 | ||||||
| 	uint32_t boxs = font->height / 9; | 	uint32_t boxs = font->height / 9; | ||||||
| @ -392,43 +393,44 @@ draw_frame(Bar *b) | |||||||
| 			continue; | 			continue; | ||||||
| 		 | 		 | ||||||
| 		if (!hide_vacant && occupied) | 		if (!hide_vacant && occupied) | ||||||
| 			pixman_image_fill_boxes(PIXMAN_OP_SRC, foreground_left, | 			pixman_image_fill_boxes(PIXMAN_OP_SRC, foreground, | ||||||
| 						&textcolor, 1, &(pixman_box32_t){ | 						&textcolor, 1, &(pixman_box32_t){ | ||||||
| 							.x1 = xpos_left + boxs, | 							.x1 = xpos_left + boxs, .x2 = xpos_left + boxs + boxw, | ||||||
| 							.x2 = xpos_left + boxs + boxw, | 							.y1 = boxs, .y2 = boxs + boxw | ||||||
| 							.y1 = boxs, |  | ||||||
| 							.y2 = boxs + boxw |  | ||||||
| 						}); | 						}); | ||||||
| 		 | 		 | ||||||
| 		if (urgent) | 		if (urgent) | ||||||
| 			xpos_left = draw_text(tags[i], xpos_left, ypos, foreground_left, background_left, | 			xpos_left = draw_text(tags[i], xpos_left, ypos, foreground, background, &urgtextcolor, | ||||||
| 					      &urgtextcolor, &urgbgcolor, b->width, b->height, b->textpadding, false); | 					      &urgbgcolor, b->width, b->height, b->textpadding, false); | ||||||
| 		else | 		else | ||||||
| 			xpos_left = draw_text(tags[i], xpos_left, ypos, foreground_left, background_left, | 			xpos_left = draw_text(tags[i], xpos_left, ypos, foreground, background, &textcolor, | ||||||
| 					      &textcolor, active ? &activecolor : &inactivecolor, b->width, b->height, b->textpadding, false); | 					      active ? &activecolor : &inactivecolor, b->width, b->height, | ||||||
|  | 					      b->textpadding, false); | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	xpos_left = draw_text(b->layout, xpos_left, ypos, foreground_left, background_left, | 	xpos_left = draw_text(b->layout, xpos_left, ypos, foreground, background, &textcolor, | ||||||
| 			      &textcolor, &inactivecolor, b->width, b->height, b->textpadding, false); | 			      &inactivecolor, b->width, b->height, b->textpadding, false); | ||||||
| 
 | 
 | ||||||
| 	xpos_right = draw_text(b->status, 0, ypos, foreground_right, background_right, | 	uint32_t status_width = TEXT_WIDTH(b->status, b->width - xpos_left, b->textpadding, true); | ||||||
| 			       &textcolor, &inactivecolor, b->width, b->height, b->textpadding, true); | 	draw_text(b->status, b->width - status_width, ypos, foreground, background, &textcolor, | ||||||
|  | 		  &inactivecolor, b->width, b->height, b->textpadding, true); | ||||||
| 
 | 
 | ||||||
| 	draw_text(b->title, 0, ypos, foreground_title, NULL, | 	xpos_left = draw_text(b->title, xpos_left, ypos, foreground, background, &textcolor, | ||||||
| 		  &textcolor, NULL, b->width, b->height, b->textpadding, false); | 			      b->selmon ? &activecolor : &inactivecolor, b->width - status_width, | ||||||
|  | 			      b->height, b->textpadding, false); | ||||||
|  | 
 | ||||||
|  | 	pixman_image_fill_boxes(PIXMAN_OP_SRC, bar, b->selmon ? &activecolor : &inactivecolor, 1, | ||||||
|  | 				&(pixman_box32_t){ | ||||||
|  | 					.x1 = xpos_left, .x2 = b->width - status_width, | ||||||
|  | 					.y1 = 0, .y2 = b->height | ||||||
|  | 				}); | ||||||
| 
 | 
 | ||||||
| 	/* Draw background and foreground on bar */ | 	/* Draw background and foreground on bar */ | ||||||
| 	pixman_image_composite32(PIXMAN_OP_OVER, foreground_title, NULL, bar, 0, 0, 0, 0, xpos_left, 0, b->width, b->height); | 	pixman_image_composite32(PIXMAN_OP_OVER, background, NULL, bar, 0, 0, 0, 0, 0, 0, b->width, b->height); | ||||||
| 	pixman_image_composite32(PIXMAN_OP_OVER, background_right, NULL, bar, 0, 0, 0, 0, b->width - xpos_right, 0, b->width, b->height); | 	pixman_image_composite32(PIXMAN_OP_OVER, foreground, NULL, bar, 0, 0, 0, 0, 0, 0, b->width, b->height); | ||||||
| 	pixman_image_composite32(PIXMAN_OP_OVER, foreground_right, NULL, bar, 0, 0, 0, 0, b->width - xpos_right, 0, b->width, b->height); |  | ||||||
| 	pixman_image_composite32(PIXMAN_OP_OVER, background_left, NULL, bar, 0, 0, 0, 0, 0, 0, b->width, b->height); |  | ||||||
| 	pixman_image_composite32(PIXMAN_OP_OVER, foreground_left, NULL, bar, 0, 0, 0, 0, 0, 0, b->width, b->height); |  | ||||||
| 
 | 
 | ||||||
| 	pixman_image_unref(foreground_left); | 	pixman_image_unref(foreground); | ||||||
| 	pixman_image_unref(background_left); | 	pixman_image_unref(background); | ||||||
| 	pixman_image_unref(foreground_right); |  | ||||||
| 	pixman_image_unref(background_right); |  | ||||||
| 	pixman_image_unref(foreground_title); |  | ||||||
| 	pixman_image_unref(bar); | 	pixman_image_unref(bar); | ||||||
| 	 | 	 | ||||||
| 	munmap(data, b->bufsize); | 	munmap(data, b->bufsize); | ||||||
| @ -517,10 +519,10 @@ output_description(void *data, struct zxdg_output_v1 *xdg_output, | |||||||
| 
 | 
 | ||||||
| static const struct zxdg_output_v1_listener output_listener = { | static const struct zxdg_output_v1_listener output_listener = { | ||||||
| 	.name = output_name, | 	.name = output_name, | ||||||
| 	.description = output_description, |  | ||||||
| 	.done = output_done, |  | ||||||
| 	.logical_position = output_logical_position, | 	.logical_position = output_logical_position, | ||||||
| 	.logical_size = output_logical_size | 	.logical_size = output_logical_size, | ||||||
|  | 	.done = output_done, | ||||||
|  | 	.description = output_description | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 kolunmi
						kolunmi