Changeset 8e7c9fe in mainline for uspace/lib/draw/font.c
- Timestamp:
- 2014-09-12T03:45:25Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c53b58e
- Parents:
- 3eb0c85 (diff), 105d8d6 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/draw/font.c
r3eb0c85 r8e7c9fe 1 1 /* 2 2 * Copyright (c) 2012 Petr Koupy 3 * Copyright (c) 2014 Martin Sucha 3 4 * All rights reserved. 4 5 * … … 34 35 */ 35 36 36 #include <assert.h>37 37 #include <malloc.h> 38 #include <errno.h> 39 #include <str.h> 38 40 39 41 #include "font.h" … … 41 43 #include "drawctx.h" 42 44 43 void font_init(font_t *font, font_decoder_type_t decoder, char *path, uint16_t points)45 font_t *font_create(font_backend_t *backend, void *backend_data) 44 46 { 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 } 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; 77 55 } 78 56 79 57 void font_release(font_t *font) 80 58 { 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]); 59 font->backend->release(font->backend_data); 60 } 61 62 int font_get_metrics(font_t *font, font_metrics_t *metrics) { 63 return font->backend->get_font_metrics(font->backend_data, metrics); 64 } 65 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 } 69 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; 85 106 } 86 107 } 87 free(font->glyphs); 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); 88 115 } 89 90 if (font->decoder) {91 font->decoder->release(font->decoder_data);92 }116 117 *width = x; 118 *height = fm.ascender + fm.descender; 119 return EOK; 93 120 } 94 121 95 void font_get_box(font_t *font, char *text, sysarg_t *width, sysarg_t *height) 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) 96 125 { 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 }126 }127 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);133 134 126 drawctx_save(context); 135 127 drawctx_set_compose(context, compose_over); 136 128 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 } 129 font_metrics_t fm; 130 int rc = font_get_metrics(font, &fm); 131 if (rc != EOK) 132 return rc; 144 133 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); 134 native_t baseline = sy + fm.ascender; 135 native_t x = sx; 150 136 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; 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; 159 149 } 160 150 } 161 ++text; 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 162 164 } 163 165 164 166 drawctx_restore(context); 165 167 source_set_mask(source, NULL, false); 168 169 return EOK; 166 170 } 167 171
Note:
See TracChangeset
for help on using the changeset viewer.