Changes in uspace/lib/draw/font.c [2cc1ec0:6d5e378] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/draw/font.c
r2cc1ec0 r6d5e378 1 1 /* 2 2 * Copyright (c) 2012 Petr Koupy 3 * Copyright (c) 2014 Martin Sucha4 3 * All rights reserved. 5 4 * … … 35 34 */ 36 35 36 #include <assert.h> 37 37 #include <malloc.h> 38 #include <errno.h>39 #include <str.h>40 38 41 39 #include "font.h" … … 43 41 #include "drawctx.h" 44 42 45 font_t *font_create(font_backend_t *backend, void *backend_data)43 void font_init(font_t *font, font_decoder_type_t decoder, char *path, uint16_t points) 46 44 { 47 font_t *font = malloc(sizeof(font_t)); 48 if (font == NULL) 49 return NULL; 50 51 font->backend = backend; 52 font->backend_data = backend_data; 53 54 return font; 45 font->points = points; 46 47 switch (decoder) { 48 case FONT_DECODER_EMBEDDED: 49 font->decoder = &fd_embedded; 50 break; 51 default: 52 font->decoder = NULL; 53 break; 54 } 55 56 if (font->decoder) { 57 font->decoder->init(path, &font->glyph_count, &font->decoder_data); 58 59 if (font->glyph_count > 0) { 60 font->glyphs = (surface_t **) malloc(sizeof(surface_t *) * font->glyph_count); 61 } else { 62 font->glyphs = NULL; 63 } 64 65 if (font->glyphs) { 66 for (size_t i = 0; i < font->glyph_count; ++i) { 67 font->glyphs[i] = NULL; 68 } 69 } else { 70 font->glyph_count = 0; 71 } 72 } else { 73 font->glyph_count = 0; 74 font->glyphs = NULL; 75 font->decoder_data = NULL; 76 } 55 77 } 56 78 57 79 void font_release(font_t *font) 58 80 { 59 font->backend->release(font->backend_data); 81 if (font->glyphs) { 82 for (size_t i = 0; i < font->glyph_count; ++i) { 83 if (font->glyphs[i]) { 84 surface_destroy(font->glyphs[i]); 85 } 86 } 87 free(font->glyphs); 88 } 89 90 if (font->decoder) { 91 font->decoder->release(font->decoder_data); 92 } 60 93 } 61 94 62 int font_get_metrics(font_t *font, font_metrics_t *metrics) { 63 return font->backend->get_font_metrics(font->backend_data, metrics); 95 void font_get_box(font_t *font, char *text, sysarg_t *width, sysarg_t *height) 96 { 97 assert(width); 98 assert(height); 99 100 (*width) = 0; 101 (*height) = 0; 102 103 if (!text) { 104 return; 105 } 106 107 while (*text) { 108 uint16_t glyph_idx = font->decoder->resolve(*text, font->decoder_data); 109 if (glyph_idx < font->glyph_count) { 110 if (!font->glyphs[glyph_idx]) { 111 font->glyphs[glyph_idx] = 112 font->decoder->render(glyph_idx, font->points); 113 } 114 115 surface_t *glyph = font->glyphs[glyph_idx]; 116 if (glyph) { 117 sysarg_t w; 118 sysarg_t h; 119 surface_get_resolution(glyph, &w, &h); 120 (*width) += w; 121 (*height) = (*height) < h ? h : (*height); 122 } 123 } 124 ++text; 125 } 64 126 } 65 127 66 int font_resolve_glyph(font_t *font, wchar_t c, glyph_id_t *glyph_id) { 67 return font->backend->resolve_glyph(font->backend_data, c, glyph_id); 68 } 128 void font_draw_text(font_t *font, drawctx_t *context, source_t *source, 129 const char *text, sysarg_t x, sysarg_t y) 130 { 131 assert(context); 132 assert(source); 69 133 70 int font_get_glyph_metrics(font_t *font, glyph_id_t glyph_id,71 glyph_metrics_t *glyph_metrics)72 {73 return font->backend->get_glyph_metrics(font->backend_data,74 glyph_id, glyph_metrics);75 }76 77 int font_render_glyph(font_t *font, drawctx_t *context, source_t *source,78 sysarg_t x, sysarg_t y, glyph_id_t glyph_id)79 {80 return font->backend->render_glyph(font->backend_data, context, source,81 x, y, glyph_id);82 }83 84 /* TODO this is bad interface */85 int font_get_box(font_t *font, char *text, sysarg_t *width, sysarg_t *height)86 {87 font_metrics_t fm;88 int rc = font_get_metrics(font, &fm);89 if (rc != EOK)90 return rc;91 92 native_t x = 0;93 94 size_t off = 0;95 while (true) {96 wchar_t c = str_decode(text, &off, STR_NO_LIMIT);97 if (c == 0)98 break;99 100 glyph_id_t glyph_id;101 rc = font_resolve_glyph(font, c, &glyph_id);102 if (rc != EOK) {103 int rc2 = font_resolve_glyph(font, U_SPECIAL, &glyph_id);104 if (rc2 != EOK) {105 return rc;106 }107 }108 109 glyph_metrics_t glyph_metrics;110 rc = font_get_glyph_metrics(font, glyph_id, &glyph_metrics);111 if (rc != EOK)112 return rc;113 114 x += glyph_metrics_get_advancement(&glyph_metrics);115 }116 117 *width = x;118 *height = fm.ascender + fm.descender;119 return EOK;120 }121 122 /* TODO this is bad interface */123 int font_draw_text(font_t *font, drawctx_t *context, source_t *source,124 const char *text, sysarg_t sx, sysarg_t sy)125 {126 134 drawctx_save(context); 127 135 drawctx_set_compose(context, compose_over); 128 136 129 font_metrics_t fm; 130 int rc = font_get_metrics(font, &fm); 131 if (rc != EOK) 132 return rc; 137 while (*text) { 138 uint16_t glyph_idx = font->decoder->resolve(*text, font->decoder_data); 139 if (glyph_idx < font->glyph_count) { 140 if (!font->glyphs[glyph_idx]) { 141 font->glyphs[glyph_idx] = 142 font->decoder->render(glyph_idx, font->points); 143 } 133 144 134 native_t baseline = sy + fm.ascender; 135 native_t x = sx; 145 surface_t *glyph = font->glyphs[glyph_idx]; 146 if (glyph) { 147 sysarg_t w; 148 sysarg_t h; 149 surface_get_resolution(glyph, &w, &h); 136 150 137 size_t off = 0; 138 while (true) { 139 wchar_t c = str_decode(text, &off, STR_NO_LIMIT); 140 if (c == 0) 141 break; 142 143 glyph_id_t glyph_id; 144 rc = font_resolve_glyph(font, c, &glyph_id); 145 if (rc != EOK) { 146 int rc2 = font_resolve_glyph(font, U_SPECIAL, &glyph_id); 147 if (rc2 != EOK) { 148 return rc; 151 transform_t transform; 152 transform_identity(&transform); 153 transform_translate(&transform, x, y); 154 source_set_transform(source, transform); 155 source_set_mask(source, glyph, false); 156 drawctx_transfer(context, x, y, w, h); 157 158 x += w; 149 159 } 150 160 } 151 152 glyph_metrics_t glyph_metrics; 153 rc = font_get_glyph_metrics(font, glyph_id, &glyph_metrics); 154 if (rc != EOK) 155 return rc; 156 157 rc = font_render_glyph(font, context, source, x, baseline, 158 glyph_id); 159 if (rc != EOK) 160 return rc; 161 162 x += glyph_metrics_get_advancement(&glyph_metrics); 163 161 ++text; 164 162 } 165 163 166 164 drawctx_restore(context); 167 165 source_set_mask(source, NULL, false); 168 169 return EOK;170 166 } 171 167
Note:
See TracChangeset
for help on using the changeset viewer.