more work on win32 fonts
							parent
							
								
									428696d95e
								
							
						
					
					
						commit
						682d99dacc
					
				
							
								
								
									
										179
									
								
								win32_font.cpp
								
								
								
								
							
							
						
						
									
										179
									
								
								win32_font.cpp
								
								
								
								
							| 
						 | 
					@ -9,6 +9,21 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TOP
 | 
					// TOP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct Glyph_Bitmap{
 | 
				
			||||||
 | 
					    HBITMAP bitmap_handle;
 | 
				
			||||||
 | 
					    char *pixels;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					win32_get_box(HDC dc, TCHAR character, int *x0, int *y0, int *x1, int *y1){
 | 
				
			||||||
 | 
					    SIZE size;
 | 
				
			||||||
 | 
					    GetTextExtentPoint32A(dc, &character, 1, &size);
 | 
				
			||||||
 | 
					    *x0 = 0;
 | 
				
			||||||
 | 
					    *y0 = 0;
 | 
				
			||||||
 | 
					    *x1 = size.cx;
 | 
				
			||||||
 | 
					    *y1 = size.cy;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal i32
 | 
					internal i32
 | 
				
			||||||
win32_draw_font_load(Partition *part,
 | 
					win32_draw_font_load(Partition *part,
 | 
				
			||||||
                     Render_Font *font_out,
 | 
					                     Render_Font *font_out,
 | 
				
			||||||
| 
						 | 
					@ -44,20 +59,172 @@ win32_draw_font_load(Partition *part,
 | 
				
			||||||
        HDC dc = CreateCompatibleDC(0);
 | 
					        HDC dc = CreateCompatibleDC(0);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if (dc){
 | 
					        if (dc){
 | 
				
			||||||
            // TODO(allen): Have to get metrics
 | 
					            TEXTMETRIC metrics;
 | 
				
			||||||
 | 
					            GetTextMetrics(dc, &metrics);
 | 
				
			||||||
 | 
					            font_out->height = metrics.tmHeight + metrics.tmExternalLeading;
 | 
				
			||||||
 | 
					            font_out->ascent = metrics.tmAscent;
 | 
				
			||||||
 | 
					            font_out->descent = -metrics.tmDescent;
 | 
				
			||||||
 | 
					            font_out->line_skip = metrics.tmExternalLeading;
 | 
				
			||||||
 | 
					            font_out->advance = metrics.tmMaxCharWidth;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            result = 1;
 | 
					            result = 1;
 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            if (store_texture){
 | 
					            if (store_texture){
 | 
				
			||||||
 | 
					                Temp_Memory temp = begin_temp_memory(part);
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                i32 tex_width = pt_size*16*oversample;
 | 
					                i32 tex_width = pt_size*16*oversample;
 | 
				
			||||||
                i32 tex_height = pt_size*16*oversample;
 | 
					                i32 tex_height = pt_size*16*oversample;
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                HBITAMP bitmap = CreateCompatibleBitmap(dc, tex_width, tex_height);
 | 
					                Glyph_Bitmap glyph_bitmap;
 | 
				
			||||||
 | 
					                glyph_bitmap.bitmap_handle = CreateCompatibleBitmap(dc, tex_width, tex_height);
 | 
				
			||||||
 | 
					                glyph_bitmap.pixels = push_array(part, char, tex_width*tex_height);
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                // TODO(allen): pack each glyph into a texture
 | 
					                SelectObject(dc, glyph_bitmap.bitmap_handle);
 | 
				
			||||||
                // and generate the equivalent data output by stb
 | 
					                SelectObject(dc, font_handle);
 | 
				
			||||||
                // in the stbtt_packedchar array.
 | 
					 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
 | 
					                SetBkColor(dc, RGB(0, 0, 0));
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                stbtt_pack_context context = {0};
 | 
				
			||||||
 | 
					                stbtt_PackBegin(&context, (unsigned char*)glyph_bitmap.pixels, tex_width, tex_height, 0, 1, part);
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    stbtt_pack_context *spc = &context;
 | 
				
			||||||
 | 
					                    int first_unicode_char_in_range = 0;
 | 
				
			||||||
 | 
					                    int num_chars_in_range = 128;
 | 
				
			||||||
 | 
					                    stbtt_packedchar *chardata_for_range = font_out->chardata;
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        stbtt_pack_range range;
 | 
				
			||||||
 | 
					                        range.first_unicode_char_in_range = first_unicode_char_in_range;
 | 
				
			||||||
 | 
					                        range.num_chars_in_range          = num_chars_in_range;
 | 
				
			||||||
 | 
					                        range.chardata_for_range          = chardata_for_range;
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            stbtt_pack_range *ranges = ⦥
 | 
				
			||||||
 | 
					                            int num_ranges = 1;
 | 
				
			||||||
 | 
					                            
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                float recip_h = 1.0f / spc->h_oversample;
 | 
				
			||||||
 | 
					                                float recip_v = 1.0f / spc->v_oversample;
 | 
				
			||||||
 | 
					                                float sub_x = stbtt__oversample_shift(spc->h_oversample);
 | 
				
			||||||
 | 
					                                float sub_y = stbtt__oversample_shift(spc->v_oversample);
 | 
				
			||||||
 | 
					                                int i,j,k,n, return_value = 1;
 | 
				
			||||||
 | 
					                                stbrp_context *context = (stbrp_context *) spc->pack_info;
 | 
				
			||||||
 | 
					                                stbrp_rect    *rects;
 | 
				
			||||||
 | 
					                                
 | 
				
			||||||
 | 
					                                // flag all characters as NOT packed
 | 
				
			||||||
 | 
					                                for (i=0; i < num_ranges; ++i)
 | 
				
			||||||
 | 
					                                    for (j=0; j < ranges[i].num_chars_in_range; ++j)
 | 
				
			||||||
 | 
					                                    ranges[i].chardata_for_range[j].x0 =
 | 
				
			||||||
 | 
					                                    ranges[i].chardata_for_range[j].y0 =
 | 
				
			||||||
 | 
					                                    ranges[i].chardata_for_range[j].x1 =
 | 
				
			||||||
 | 
					                                    ranges[i].chardata_for_range[j].y1 = 0;
 | 
				
			||||||
 | 
					                                
 | 
				
			||||||
 | 
					                                n = 0;
 | 
				
			||||||
 | 
					                                for (i=0; i < num_ranges; ++i)
 | 
				
			||||||
 | 
					                                    n += ranges[i].num_chars_in_range;
 | 
				
			||||||
 | 
					                                
 | 
				
			||||||
 | 
					                                rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context);
 | 
				
			||||||
 | 
					                                if (rects == NULL)
 | 
				
			||||||
 | 
					                                    return 0;
 | 
				
			||||||
 | 
					                                
 | 
				
			||||||
 | 
					                                k=0;
 | 
				
			||||||
 | 
					                                for (i=0; i < num_ranges; ++i) {
 | 
				
			||||||
 | 
					                                    for (j=0; j < ranges[i].num_chars_in_range; ++j) {
 | 
				
			||||||
 | 
					                                        int x0,y0,x1,y1;
 | 
				
			||||||
 | 
					                                        
 | 
				
			||||||
 | 
					                                        TCHAR character = (TCHAR)(ranges[i].first_unicode_char_in_range + j);
 | 
				
			||||||
 | 
					                                        win32_get_box(dc, character, &x0, &y0, &x1, &y1);
 | 
				
			||||||
 | 
					                                        
 | 
				
			||||||
 | 
					                                        rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
 | 
				
			||||||
 | 
					                                        rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
 | 
				
			||||||
 | 
					                                        ++k;
 | 
				
			||||||
 | 
					                                    }
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                                
 | 
				
			||||||
 | 
					                                stbrp_pack_rects(context, rects, k);
 | 
				
			||||||
 | 
					                                
 | 
				
			||||||
 | 
					                                k = 0;
 | 
				
			||||||
 | 
					                                for (i=0; i < num_ranges; ++i) {
 | 
				
			||||||
 | 
					                                    for (j=0; j < ranges[i].num_chars_in_range; ++j) {
 | 
				
			||||||
 | 
					                                        stbrp_rect *r = &rects[k];
 | 
				
			||||||
 | 
					                                        if (r->was_packed) {
 | 
				
			||||||
 | 
					                                            stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
 | 
				
			||||||
 | 
					                                            int advance, x0,y0,x1,y1;
 | 
				
			||||||
 | 
					                                            int glyph = ranges[i].first_unicode_char_in_range + j;
 | 
				
			||||||
 | 
					                                            stbrp_coord pad = (stbrp_coord) spc->padding;
 | 
				
			||||||
 | 
					                                            
 | 
				
			||||||
 | 
					                                            GetCharWidth32W(dc, glyph, glyph, &advance);
 | 
				
			||||||
 | 
					                                            
 | 
				
			||||||
 | 
					                                            TCHAR character = (TCHAR)(ranges[i].first_unicode_char_in_range + j);
 | 
				
			||||||
 | 
					                                            win32_get_box(dc, character, &x0, &y0, &x1, &y1);
 | 
				
			||||||
 | 
					                                            
 | 
				
			||||||
 | 
					                                            // pad on left and top
 | 
				
			||||||
 | 
					                                            r->x += pad;
 | 
				
			||||||
 | 
					                                            r->y += pad;
 | 
				
			||||||
 | 
					                                            r->w -= pad;
 | 
				
			||||||
 | 
					                                            r->h -= pad;
 | 
				
			||||||
 | 
					                                            
 | 
				
			||||||
 | 
					                                            SetTextColor(dc, RGB(255, 255, 255));
 | 
				
			||||||
 | 
					                                            TextOutA(dc, r->x, r->y, &character, 1);
 | 
				
			||||||
 | 
					                                            
 | 
				
			||||||
 | 
					                                            if (spc->h_oversample > 1)
 | 
				
			||||||
 | 
					                                                stbtt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
 | 
				
			||||||
 | 
					                                                                   r->w, r->h, spc->stride_in_bytes,
 | 
				
			||||||
 | 
					                                                                   spc->h_oversample);
 | 
				
			||||||
 | 
					                                            
 | 
				
			||||||
 | 
					                                            if (spc->v_oversample > 1)
 | 
				
			||||||
 | 
					                                                stbtt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
 | 
				
			||||||
 | 
					                                                                   r->w, r->h, spc->stride_in_bytes,
 | 
				
			||||||
 | 
					                                                                   spc->v_oversample);
 | 
				
			||||||
 | 
					                                            
 | 
				
			||||||
 | 
					                                            bc->x0       = (stbtt_int16)  r->x;
 | 
				
			||||||
 | 
					                                            bc->y0       = (stbtt_int16)  r->y;
 | 
				
			||||||
 | 
					                                            bc->x1       = (stbtt_int16) (r->x + r->w);
 | 
				
			||||||
 | 
					                                            bc->y1       = (stbtt_int16) (r->y + r->h);
 | 
				
			||||||
 | 
					                                            bc->xadvance =                (float) advance;
 | 
				
			||||||
 | 
					                                            bc->xoff     =       (float)  x0 * recip_h + sub_x;
 | 
				
			||||||
 | 
					                                            bc->yoff     =       (float)  y0 * recip_v + sub_y;
 | 
				
			||||||
 | 
					                                            bc->xoff2    =                (x0 + r->w) * recip_h + sub_x;
 | 
				
			||||||
 | 
					                                            bc->yoff2    =                (y0 + r->h) * recip_v + sub_y;
 | 
				
			||||||
 | 
					                                        } else {
 | 
				
			||||||
 | 
					                                            return_value = 0; // if any fail, report failure
 | 
				
			||||||
 | 
					                                        }
 | 
				
			||||||
 | 
					                                        
 | 
				
			||||||
 | 
					                                        ++k;
 | 
				
			||||||
 | 
					                                    }
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                                
 | 
				
			||||||
 | 
					                                STBTT_free(rects, spc->user_allocator_context);
 | 
				
			||||||
 | 
					                                
 | 
				
			||||||
 | 
					                                result = return_value;
 | 
				
			||||||
 | 
					                                
 | 
				
			||||||
 | 
					                                if (return_value){
 | 
				
			||||||
 | 
					                                    GLuint font_tex;
 | 
				
			||||||
 | 
					                                    glGenTextures(1, &font_tex);
 | 
				
			||||||
 | 
					                                    glBindTexture(GL_TEXTURE_2D, font_tex);
 | 
				
			||||||
 | 
					                                    
 | 
				
			||||||
 | 
					                                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 | 
				
			||||||
 | 
					                                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 | 
				
			||||||
 | 
					                                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 | 
				
			||||||
 | 
					                                    
 | 
				
			||||||
 | 
					                                    glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, glyph_bitmap.pixels);
 | 
				
			||||||
 | 
					                                    
 | 
				
			||||||
 | 
					                                    font_out->tex = font_tex;
 | 
				
			||||||
 | 
					                                    glBindTexture(GL_TEXTURE_2D, 0);
 | 
				
			||||||
 | 
					                                    
 | 
				
			||||||
 | 
					                                    font_out->chardata['\r'] = font_out->chardata[' '];
 | 
				
			||||||
 | 
					                                    font_out->chardata['\n'] = font_out->chardata[' '];
 | 
				
			||||||
 | 
					                                    font_out->chardata['\t'] = font_out->chardata[' '];
 | 
				
			||||||
 | 
					                                    font_out->chardata['\t'].xadvance *= tab_width;
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                stbtt_PackEnd(&context);
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                end_temp_memory(temp);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue