Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2010 LunarG, Inc.  All Rights Reserved.
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the
  7.  * "Software"), to deal in the Software without restriction, including
  8.  * without limitation the rights to use, copy, modify, merge, publish,
  9.  * distribute, sub license, and/or sell copies of the Software, and to
  10.  * permit persons to whom the Software is furnished to do so, subject to
  11.  * the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice (including the
  14.  * next paragraph) shall be included in all copies or substantial portions
  15.  * of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  20.  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  21.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  22.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  23.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24.  *
  25.  **************************************************************************/
  26.  
  27. #include "util/u_memory.h"
  28. #include "cso_cache/cso_hash.h"
  29.  
  30. #include "text.h"
  31. #include "image.h"
  32. #include "path.h"
  33.  
  34. #ifdef OPENVG_VERSION_1_1
  35.  
  36. struct vg_font {
  37.    struct vg_object base;
  38.    struct cso_hash *glyphs;
  39. };
  40.  
  41. struct vg_glyph {
  42.    struct vg_object *object; /* it could be NULL */
  43.    VGboolean is_hinted;
  44.    VGfloat glyph_origin[2];
  45.    VGfloat escapement[2];
  46. };
  47.  
  48. static VGboolean del_glyph(struct vg_font *font,
  49.                            VGuint glyphIndex)
  50. {
  51.    struct vg_glyph *glyph;
  52.  
  53.    glyph = (struct vg_glyph *)
  54.       cso_hash_take(font->glyphs, (unsigned) glyphIndex);
  55.    FREE(glyph);
  56.  
  57.    return (glyph != NULL);
  58. }
  59.  
  60. static void add_glyph(struct vg_font *font,
  61.                       VGuint glyphIndex,
  62.                       struct vg_object *obj,
  63.                       VGboolean isHinted,
  64.                       const VGfloat glyphOrigin[2],
  65.                       const VGfloat escapement[2])
  66. {
  67.    struct vg_glyph *glyph;
  68.  
  69.    /* remove the existing one */
  70.    del_glyph(font, glyphIndex);
  71.  
  72.    glyph = CALLOC_STRUCT(vg_glyph);
  73.    glyph->object = obj;
  74.    glyph->is_hinted = isHinted;
  75.    memcpy(glyph->glyph_origin, glyphOrigin, sizeof(glyph->glyph_origin));
  76.    memcpy(glyph->escapement, escapement, sizeof(glyph->glyph_origin));
  77.  
  78.    cso_hash_insert(font->glyphs, (unsigned) glyphIndex, glyph);
  79. }
  80.  
  81. static struct vg_glyph *get_glyph(struct vg_font *font,
  82.                                   VGuint glyphIndex)
  83. {
  84.    struct cso_hash_iter iter;
  85.  
  86.    iter = cso_hash_find(font->glyphs, (unsigned) glyphIndex);
  87.    return (struct vg_glyph *) cso_hash_iter_data(iter);
  88. }
  89.  
  90. static void vg_render_glyph(struct vg_context *ctx,
  91.                             struct vg_glyph *glyph,
  92.                             VGbitfield paintModes,
  93.                             VGboolean allowAutoHinting)
  94. {
  95.    if (glyph->object && paintModes) {
  96.       struct vg_state *state = &ctx->state.vg;
  97.       struct matrix m;
  98.  
  99.       m = state->glyph_user_to_surface_matrix;
  100.       matrix_translate(&m,
  101.             state->glyph_origin[0].f - glyph->glyph_origin[0],
  102.             state->glyph_origin[1].f - glyph->glyph_origin[1]);
  103.  
  104.       if (glyph->object->type == VG_OBJECT_PATH) {
  105.          path_render((struct path *) glyph->object, paintModes, &m);
  106.       }
  107.       else {
  108.          assert(glyph->object->type == VG_OBJECT_IMAGE);
  109.          image_draw((struct vg_image *) glyph->object, &m);
  110.       }
  111.    }
  112. }
  113.  
  114. static void vg_advance_glyph(struct vg_context *ctx,
  115.                              struct vg_glyph *glyph,
  116.                              VGfloat adjustment_x,
  117.                              VGfloat adjustment_y,
  118.                              VGboolean last)
  119. {
  120.    struct vg_value *glyph_origin = ctx->state.vg.glyph_origin;
  121.  
  122.    glyph_origin[0].f += glyph->escapement[0] + adjustment_x;
  123.    glyph_origin[1].f += glyph->escapement[1] + adjustment_y;
  124.  
  125.    if (last) {
  126.       glyph_origin[0].i = float_to_int_floor(glyph_origin[0].f);
  127.       glyph_origin[1].i = float_to_int_floor(glyph_origin[1].f);
  128.    }
  129. }
  130.  
  131. struct vg_font *font_create(VGint glyphCapacityHint)
  132. {
  133.    struct vg_context *ctx = vg_current_context();
  134.    struct vg_font *font;
  135.  
  136.    font = CALLOC_STRUCT(vg_font);
  137.    vg_init_object(&font->base, ctx, VG_OBJECT_FONT);
  138.    font->glyphs = cso_hash_create();
  139.  
  140.    vg_context_add_object(ctx, &font->base);
  141.  
  142.    return font;
  143. }
  144.  
  145. void font_destroy(struct vg_font *font)
  146. {
  147.    struct vg_context *ctx = vg_current_context();
  148.    struct cso_hash_iter iter;
  149.  
  150.    vg_context_remove_object(ctx, &font->base);
  151.  
  152.    iter = cso_hash_first_node(font->glyphs);
  153.    while (!cso_hash_iter_is_null(iter)) {
  154.       struct vg_glyph *glyph = (struct vg_glyph *) cso_hash_iter_data(iter);
  155.       FREE(glyph);
  156.       iter = cso_hash_iter_next(iter);
  157.    }
  158.    cso_hash_delete(font->glyphs);
  159.  
  160.    vg_free_object(&font->base);
  161.  
  162.    FREE(font);
  163. }
  164.  
  165. void font_set_glyph_to_path(struct vg_font *font,
  166.                             VGuint glyphIndex,
  167.                             struct path *path,
  168.                             VGboolean isHinted,
  169.                             const VGfloat glyphOrigin[2],
  170.                             const VGfloat escapement[2])
  171. {
  172.    add_glyph(font, glyphIndex, (struct vg_object *) path,
  173.          isHinted, glyphOrigin, escapement);
  174. }
  175.  
  176. void font_set_glyph_to_image(struct vg_font *font,
  177.                              VGuint glyphIndex,
  178.                              struct vg_image *image,
  179.                              const VGfloat glyphOrigin[2],
  180.                              const VGfloat escapement[2])
  181. {
  182.    add_glyph(font, glyphIndex, (struct vg_object *) image,
  183.          VG_TRUE, glyphOrigin, escapement);
  184. }
  185.  
  186. void font_clear_glyph(struct vg_font *font,
  187.                       VGuint glyphIndex)
  188. {
  189.    if (!del_glyph(font, glyphIndex)) {
  190.       struct vg_context *ctx = vg_current_context();
  191.       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
  192.    }
  193. }
  194.  
  195. void font_draw_glyph(struct vg_font *font,
  196.                      VGuint glyphIndex,
  197.                      VGbitfield paintModes,
  198.                      VGboolean allowAutoHinting)
  199. {
  200.    struct vg_context *ctx = vg_current_context();
  201.    struct vg_glyph *glyph;
  202.  
  203.    glyph = get_glyph(font, glyphIndex);
  204.    if (!glyph) {
  205.       vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
  206.       return;
  207.    }
  208.  
  209.    vg_render_glyph(ctx, glyph, paintModes, allowAutoHinting);
  210.    vg_advance_glyph(ctx, glyph, 0.0f, 0.0f, VG_TRUE);
  211. }
  212.  
  213. void font_draw_glyphs(struct vg_font *font,
  214.                       VGint glyphCount,
  215.                       const VGuint *glyphIndices,
  216.                       const VGfloat *adjustments_x,
  217.                       const VGfloat *adjustments_y,
  218.                       VGbitfield paintModes,
  219.                       VGboolean allowAutoHinting)
  220. {
  221.    struct vg_context *ctx = vg_current_context();
  222.    VGint i;
  223.  
  224.    for (i = 0; i < glyphCount; ++i) {
  225.       if (!get_glyph(font, glyphIndices[i])) {
  226.          vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
  227.          return;
  228.       }
  229.    }
  230.  
  231.    for (i = 0; i < glyphCount; ++i) {
  232.       struct vg_glyph *glyph;
  233.       VGfloat adj_x, adj_y;
  234.  
  235.       glyph = get_glyph(font, glyphIndices[i]);
  236.  
  237.       vg_render_glyph(ctx, glyph, paintModes, allowAutoHinting);
  238.  
  239.       adj_x = (adjustments_x) ? adjustments_x[i] : 0.0f;
  240.       adj_y = (adjustments_y) ? adjustments_y[i] : 0.0f;
  241.       vg_advance_glyph(ctx, glyph, adj_x, adj_y, (i == glyphCount - 1));
  242.    }
  243. }
  244.  
  245. VGint font_num_glyphs(struct vg_font *font)
  246. {
  247.    return cso_hash_size(font->glyphs);
  248. }
  249.  
  250. #endif /* OPENVG_VERSION_1_1 */
  251.