Changes in uspace/lib/draw/font.c [2cc1ec0:6d5e378] in mainline


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/draw/font.c

    r2cc1ec0 r6d5e378  
    11/*
    22 * Copyright (c) 2012 Petr Koupy
    3  * Copyright (c) 2014 Martin Sucha
    43 * All rights reserved.
    54 *
     
    3534 */
    3635
     36#include <assert.h>
    3737#include <malloc.h>
    38 #include <errno.h>
    39 #include <str.h>
    4038
    4139#include "font.h"
     
    4341#include "drawctx.h"
    4442
    45 font_t *font_create(font_backend_t *backend, void *backend_data)
     43void font_init(font_t *font, font_decoder_type_t decoder, char *path, uint16_t points)
    4644{
    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        }
    5577}
    5678
    5779void font_release(font_t *font)
    5880{
    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        }
    6093}
    6194
    62 int font_get_metrics(font_t *font, font_metrics_t *metrics) {
    63         return font->backend->get_font_metrics(font->backend_data, metrics);
     95void 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        }
    64126}
    65127
    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 }
     128void 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);
    69133
    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 {
    126134        drawctx_save(context);
    127135        drawctx_set_compose(context, compose_over);
    128136
    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                        }
    133144
    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);
    136150
    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;
    149159                        }
    150160                }
    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;
    164162        }
    165163
    166164        drawctx_restore(context);
    167165        source_set_mask(source, NULL, false);
    168 
    169         return EOK;
    170166}
    171167
Note: See TracChangeset for help on using the changeset viewer.